altfi_SU
altfi_SU

Reputation: 594

Subset vector by value and corresponding name

I have two named vectors. The first (foo) is a lookup vector. The second (bar) holds values that are generated in each run of a simulation. In a run, bar might not be the same length as foo and return different values for the same name and in random order; hence the two values for b, and z and a are in positions 1 and 4, respectively.

How can one subset bar so that it returns the values not in foo with the corresponding names? The desired output can be seen with bar2.

foo <- c(a = 5, b = 5, c = 5, d = 4, e = 5, z = 5) # lookup vector
bar <- c(z = 5, b = 4, b = 3, a = 5, e = 2)        # data

bar2 <- c(b = 4, b = 3, e = 2)                     # desired output

> bar2
b b e 
4 3 2 

Upvotes: 1

Views: 205

Answers (2)

r.user.05apr
r.user.05apr

Reputation: 5456

You could combine names and values:

bar[!paste0(bar, names(bar)) %in% paste0(foo, names(foo))]

#b b e 
#4 3 2 

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388807

One way using mapply :

bar[mapply(function(x, y) !any(names(foo) %in% x & foo %in% y), names(bar), bar)]

#b b e 
#4 3 2 

Similar logic with purrr's imap_lgl.

bar[purrr::imap_lgl(bar, ~!any(foo %in% .x & names(foo) %in% .y))]

Upvotes: 1

Related Questions