Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Test if Lists Contain String

Tags:

list

r

I have a string of numbers, and a list:

 a <- c(1,2,3)
 b <- list( x<-c(1:5),y<-c(1:10),z<-c(10:20))

What I want to do is to test whether each number is in each element of the list -- whether 1 is in x, 2 is in y, 3 is in z. And then give 1/0 to a new variable.

My code:

d <- ifelse(a %in% sapply(b,function(x) unlist(x)),1,0)

However the result:

> d
[1] 0 0 0

And desirable result should be:

[1] 1 1 0

How can I do this? Thank you

like image 675
Elmer LI Avatar asked Aug 12 '16 01:08

Elmer LI


4 Answers

You're looping over two matching sets of data, which suggests Map/mapply:

mapply(`%in%`, a, b)
#[1]  TRUE  TRUE FALSE

as.integer(mapply(`%in%`, a, b))
#[1] 1 1 0
like image 137
thelatemail Avatar answered Nov 06 '22 04:11

thelatemail


The purrr package has a number of variations on the *apply family and helper functions useful for working with lists. In this case, it would look like

library(purrr)

map2_int(a, b, ~.x %in% .y)    # shorthand for map2_int(a, b, function(x, y){x %in% y})
## [1] 1 1 0

or

map2_int(a, b, `%in%`)
## [1] 1 1 0

where

  • the map part is the name of a set of functions that apply a function to the elements of a list,
  • the 2 part is a version that takes two lists as input and iterates over them in parallel, and
  • the _int part is a version that simplifies the result to an integer vector.
like image 32
alistaire Avatar answered Nov 06 '22 04:11

alistaire


It is worth noting that is.element is the equivalent of %in%, so you can avoid typing some quotation marks. If you like purrr, you can get the right answer with

map2_int(a,b, is.element)

[1] 1 1 0
like image 34
shayaa Avatar answered Nov 06 '22 05:11

shayaa


The best way to mimic a for loop with apply functions is to actually define an iterator.

sapply(1:length(b), function(i) a[i] %in% b[[i]])

This will return booleans [1] TRUE TRUE FALSE

convert to int with as.integer()

I feel like this is more intuitive than mapply, and with a self-defined function call, you can tweak around with it, say making a if statement searching for NA lists.

like image 29
fhlgood Avatar answered Nov 06 '22 06:11

fhlgood