2

I have the following character fields I am trying to intersect. These should be equal.

> char.y[[892]]
 [1] "E" "d" "w" "a" "r" "d" "s" " " "L" "i" "f" "e" "s" "c" "i" "e" "n" "c" "e" "s"
> char.x[[892]]
 [1] "E" "d" "w" "a" "r" "d" "s" " " "L" "i" "f" "e" "s" "c" "i" "e" "n" "c" "e" "s"
> intersect(char.x[[892]], char.y[[892]])
 [1] "E" "d" "w" "a" "r" "s" " " "L" "i" "f" "e" "c" "n"
> 

expected result:

"E" "d" "w" "a" "r" "d" "s" " " "L" "i" "f" "e" "s" "c" "i" "e" "n" "c" "e"
Dharman
  • 30,962
  • 25
  • 85
  • 135
Alex Bădoi
  • 830
  • 2
  • 9
  • 24
  • 2
    Maybe you're looking for `setequal`? `intersect` gives you the common (non-duplicated) elements between the two vectors. E.g. `intersect(c("a","b"), c("b","c"))` gives `"b"` – Mike H. Nov 30 '17 at 15:20
  • Thanks Mike but the output should result in common characters in both strings. I need this rather than a true/ false answer – Alex Bădoi Nov 30 '17 at 15:22
  • right so, 'non-duplicate' is where my issue is. is there a way to achieve this and include dups? – Alex Bădoi Nov 30 '17 at 15:24
  • 1
    That is a more complicated question because what do you do for example when your vectors are `c("b","b")` and `c("b")`? Do you want just `"b"` or `c("b","b")` returned? – Mike H. Nov 30 '17 at 15:26
  • It removes the double entries I believe, so it already returned an "s" and wont do it a second time – Fini Nov 30 '17 at 15:23

5 Answers5

3

Using intersect will return the common elements, but will not have them duplicated. For example, s is in there 3 times, but will be in the intersect only once.

If you want to see the same layout, with non intersect values removed, for example, you can use the following:

a <- c("E", "d", "w", "a", "r", "d", "s", " ", "L", "i", "f", "e", "s", "c", "i", "e", "n", "c", "e", "s")
b <- c("E", "d", "w", "a", "r", "d", "s", " ", "L", "i", "f", "e", "s", "c", "i", "e", "n", "c", "e", "s")
a[a %in% intersect(a, b)]
#  [1] "E" "d" "w" "a" "r" "d" "s" " " "L" "i" "f" "e" "s" "c" "i" "e" "n" "c" "e" "s"
Eric Watt
  • 3,180
  • 9
  • 21
  • 2
    `vecsets::vintersect(a, b)` – d.b Nov 30 '17 at 15:39
  • Don't think I've used `vecsets` before, thanks for bringing it to my attention. That returns `"E" "d" "d" "w" "a" "r" "s" "s" "s" " " "L" "i" "i" "f" "e" "e" "e" "c" "c" "n"`, which is different than what the OP was expecting I think. – Eric Watt Nov 30 '17 at 15:43
1

This would entirely depend on the vectors you are comparing (and which order) but would this be sufficient?

b <- a <- c('E', 'd', 'w', 'a', 'r', 'd', 's', '', 'L', 'i', 'f', 'e', 's', 'c', 'i', 'e', 'n', 'c', 'e')
c <- letters[sample(1:26,100, rep=T)]

a[is.element(a,b)]
#  [1] "E" "d" "w" "a" "r" "d" "s" ""  "L" "i" "f" "e" "s" "c" "i" "e" "n" "c" "e"

a[is.element(a,c)]
# [1] "d" "w" "a" "r" "d" "s" "i" "f" "e" "s" "c" "i" "e" "n" "c" "e"
TJGorrie
  • 386
  • 3
  • 13
1

I had the exact same problem and didn't find a solution, so I created my own little function "intersectdup":

intersectdup <- function(vektor1, vektor2) {
    result <- c()
    for (i in 1:length(vektor2)) {
        if (is.element(vektor2[i], vektor1)){
            result <- c(result, vektor2[i])
            foundAt <- match(vektor2[i], vektor1)
            vektor1 <- c(vektor1[1:foundAt-1], vektor1[foundAt+1:length(vektor1)])
        }
    }
    return(result)
}
Clemens
  • 11
  • 1
  • 1
    Can you say why you could not find a solution or why the previously accepted answers did not meet your needs? – Peter Apr 26 '20 at 11:00
  • GCF of 126 and 108 ... get prime factors and find their intersect with duplicates – mshaffer Apr 18 '21 at 16:56
0

Picking up on Clemens, here is a simple function in a c-based structure:

intersectMe = function(x, y, duplicates=TRUE)
    {
    xyi = intersect(x,y);
    if(!duplicates) { return (xyi); }
    
    res = c();  
    for(xy in xyi)
        {
        y.xy = which(y == xy);  ny.xy = length(y.xy);
        x.xy = which(x == xy);  nx.xy = length(x.xy);
        
        min.xy = min(ny.xy, nx.xy);
        
        res = c(res, rep(xy, min.xy) );
        }
    
    res;    
    }
mshaffer
  • 959
  • 1
  • 9
  • 19
0

vecsets library also helps (using on example created by Eric)

vecsets::vintersect(a, b)

 [1] "E" "d" "d" "w" "a" "r" "s" "s" "s" " " "L" "i" "i" "f" "e" "e" "e" "c" "c" "n"
AnilGoyal
  • 25,297
  • 4
  • 27
  • 45