Reputation: 9878
I have a list of 4 logical vectors (mylist):
list(a = c(NA, FALSE, FALSE, TRUE, FALSE, NA, NA, NA, FALSE,
FALSE, FALSE, FALSE, NA, FALSE, NA, FALSE, FALSE, TRUE, TRUE,
TRUE, TRUE, NA, FALSE, NA, TRUE, FALSE, FALSE, NA, TRUE, FALSE,
NA, TRUE, NA, TRUE, FALSE, NA, NA, NA, NA, FALSE, NA, NA, NA,
NA, FALSE, FALSE, TRUE, NA, NA, NA, FALSE, NA, NA, TRUE, NA,
FALSE, TRUE, NA, FALSE, TRUE, NA, NA, NA, NA, FALSE, NA, FALSE,
NA, NA, NA, FALSE, TRUE, TRUE, NA, TRUE, NA, NA, FALSE, FALSE,
TRUE, NA, FALSE, FALSE, FALSE, NA, NA, FALSE, NA, FALSE, NA,
FALSE, NA, NA, NA, NA, FALSE, NA, TRUE, TRUE, FALSE, TRUE, NA,
FALSE, TRUE, NA, TRUE, NA, TRUE, FALSE, NA, NA, FALSE, TRUE,
FALSE, NA, FALSE, NA, TRUE, FALSE, NA, FALSE, FALSE, NA, TRUE,
TRUE, NA, FALSE, TRUE, FALSE, FALSE, NA, NA, NA, NA, TRUE, FALSE,
NA, NA, FALSE, NA, NA, NA, NA, NA, TRUE, NA, NA, FALSE, TRUE,
NA, NA, NA, FALSE, NA, NA, NA, NA, NA, TRUE, TRUE, NA, FALSE,
NA, NA, FALSE, NA, FALSE, TRUE, TRUE, FALSE, TRUE, NA, TRUE,
NA, NA), b = c(NA, FALSE, FALSE, FALSE, FALSE, NA, NA, NA, FALSE,
FALSE, FALSE, FALSE, NA, TRUE, NA, FALSE, TRUE, TRUE, FALSE,
FALSE, FALSE, NA, FALSE, NA, FALSE, FALSE, FALSE, NA, TRUE, FALSE,
NA, TRUE, NA, FALSE, FALSE, NA, NA, NA, NA, FALSE, NA, NA, NA,
NA, FALSE, FALSE, TRUE, NA, NA, NA, FALSE, NA, NA, FALSE, NA,
FALSE, TRUE, NA, FALSE, TRUE, NA, NA, NA, NA, TRUE, NA, FALSE,
NA, NA, NA, FALSE, TRUE, TRUE, NA, TRUE, NA, NA, FALSE, FALSE,
FALSE, NA, FALSE, FALSE, FALSE, NA, NA, FALSE, NA, TRUE, NA,
TRUE, NA, NA, NA, NA, FALSE, NA, TRUE, TRUE, FALSE, FALSE, NA,
FALSE, FALSE, NA, FALSE, NA, TRUE, FALSE, NA, NA, TRUE, FALSE,
FALSE, NA, TRUE, NA, FALSE, FALSE, NA, FALSE, TRUE, NA, FALSE,
FALSE, NA, TRUE, TRUE, FALSE, FALSE, NA, NA, NA, NA, TRUE, FALSE,
NA, NA, TRUE, NA, NA, NA, NA, NA, FALSE, NA, NA, TRUE, TRUE,
NA, NA, NA, FALSE, NA, NA, NA, NA, NA, FALSE, FALSE, NA, FALSE,
NA, NA, FALSE, NA, TRUE, TRUE, FALSE, FALSE, FALSE, NA, FALSE,
NA, NA), c = c(NA, FALSE, FALSE, FALSE, FALSE, NA, NA, NA, FALSE,
FALSE, TRUE, FALSE, NA, FALSE, NA, TRUE, TRUE, TRUE, FALSE, FALSE,
TRUE, NA, TRUE, NA, FALSE, FALSE, FALSE, NA, TRUE, FALSE, NA,
TRUE, NA, FALSE, FALSE, NA, NA, NA, NA, FALSE, NA, NA, NA, NA,
FALSE, FALSE, TRUE, NA, NA, NA, FALSE, NA, NA, FALSE, NA, FALSE,
TRUE, NA, FALSE, FALSE, NA, NA, NA, NA, FALSE, NA, TRUE, NA,
NA, NA, FALSE, TRUE, TRUE, NA, TRUE, NA, NA, FALSE, FALSE, FALSE,
NA, FALSE, FALSE, TRUE, NA, NA, FALSE, NA, TRUE, NA, TRUE, NA,
NA, NA, NA, FALSE, NA, FALSE, TRUE, FALSE, FALSE, NA, TRUE, FALSE,
NA, FALSE, NA, TRUE, FALSE, NA, NA, FALSE, FALSE, FALSE, NA,
TRUE, NA, FALSE, FALSE, NA, TRUE, FALSE, NA, FALSE, FALSE, NA,
TRUE, FALSE, FALSE, FALSE, NA, NA, NA, NA, FALSE, FALSE, NA,
NA, TRUE, NA, NA, NA, NA, NA, FALSE, NA, NA, TRUE, TRUE, NA,
NA, NA, FALSE, NA, NA, NA, NA, NA, FALSE, TRUE, NA, FALSE, NA,
NA, FALSE, NA, FALSE, TRUE, FALSE, FALSE, TRUE, NA, FALSE, NA,
NA), d = c(NA, FALSE, FALSE, FALSE, FALSE, NA, NA, NA, FALSE,
FALSE, FALSE, FALSE, NA, FALSE, NA, FALSE, FALSE, TRUE, FALSE,
FALSE, FALSE, NA, FALSE, NA, FALSE, FALSE, FALSE, NA, FALSE,
FALSE, NA, TRUE, NA, FALSE, FALSE, NA, NA, NA, NA, FALSE, NA,
NA, NA, NA, FALSE, FALSE, TRUE, NA, NA, NA, FALSE, NA, NA, FALSE,
NA, FALSE, FALSE, NA, FALSE, FALSE, NA, NA, NA, NA, FALSE, NA,
FALSE, NA, NA, NA, FALSE, TRUE, FALSE, NA, FALSE, NA, NA, FALSE,
FALSE, TRUE, NA, FALSE, FALSE, FALSE, NA, NA, FALSE, NA, FALSE,
NA, TRUE, NA, NA, NA, NA, FALSE, NA, FALSE, TRUE, FALSE, FALSE,
NA, FALSE, FALSE, NA, FALSE, NA, FALSE, FALSE, NA, NA, FALSE,
FALSE, FALSE, NA, FALSE, NA, FALSE, FALSE, NA, TRUE, FALSE, NA,
FALSE, FALSE, NA, FALSE, FALSE, FALSE, FALSE, NA, NA, NA, NA,
TRUE, FALSE, NA, NA, FALSE, NA, NA, NA, NA, NA, FALSE, NA, NA,
FALSE, FALSE, NA, NA, NA, FALSE, NA, NA, NA, NA, NA, FALSE, FALSE,
NA, FALSE, NA, NA, FALSE, NA, FALSE, FALSE, FALSE, FALSE, FALSE,
NA, TRUE, NA, NA))
I want a function that would return a logical vector with TRUE values when ANY corresponding value from the original vectors is TRUE (output_vector). When any of the following: (mylist[[1]][[i]], mylist[[2]][[i]], mylist[[3]][[i]], mylist[[4]][[i]]) is TRUE, output_vector[i] should be TRUE.
I came up with two solutions, one with nested for loops, the other with mapply:
#Nested for loops:
my_function<-function(){
my_vector<-logical(length(mylist[[1]]))
for (i in 1:length(mylist[[1]])){
for (j in 1:length(mylist)){
my_vector[i]<-any(mylist[[j]][[i]]==T)
}
}
my_vector
}
my_function()
mapply(any, mylist[[1]], mylist[[2]], mylist[[3]], mylist[[4]])
I am surprised because: 1-) the #mapply and #nested for loops methods yielded different results
Maybe there is something wrong with the nested for loops method? mapply looks much cleaner and wielded results in line with my expectations, though.
bonus question: is there a way to use some sort of do.call() in the mapply method so that I do not have to write out every argument to any()?
Upvotes: 1
Views: 220
Reputation: 102920
Here is another base R option that may apply to your question
colSums(do.call(rbind,mylist))>1
where the number of TRUE
s in columns is counted. If there exists a NA
, then a NA
is returned.
Upvotes: 1
Reputation: 887981
If we need an elementwise comparison, use Reduce
out1 <- Reduce(`|`, mylist)
which is similar to the do.call
method with Map
and any
out2 <- unlist(do.call(Map, c(f = any, mylist)))
all.equal(out1, out2)
#[1] TRUE
In the nested for
loop
mylist[[j]][[i]]
is a single element in the list
which is getting wrapped with any
. Therefore, the my_vector
which was initialized as the length
of the first vector
element of 'mylist' is getting recycled and it will return the output of the last list
element
If we make a small change in the function
for
loop, it would give the same output i.e. the key is to check whether the elements in 'my_vector' at the same position along with the element indexed from 'mylist' have any
TRUE values instead of just checking a single element and overwriting it to my_vector
my_function<-function(){
my_vector <- logical(length(mylist[[1]]))
for (i in 1:length(mylist[[1]])){
for (j in 1:length(mylist)){
my_vector[i] <- any(c(my_vector[i], mylist[[j]][[i]]))
}
}
my_vector
}
out3 <- my_function()
identical(out1, out3)
#[1] TRUE
Upvotes: 1