Как сравнить два списка в R - PullRequest
1 голос
/ 27 мая 2020

У меня есть два списка, которые я хочу сравнить. Я хочу посмотреть, равны ли значения каждого элемента списка.

> m1
[[1]]
integer(0)

[[2]]
[1] 3 4

[[3]]
integer(0)

[[4]]
[1] 1

[[5]]
[1] 2 3 4

> m3
[[1]]
[1] 3

[[2]]
[1] 1 4

[[3]]
[1] 2

[[4]]
[1] 3

[[5]]
[1] 1 4

И я ожидаю такого результата:

> Result
[[1]]
[1]
FALSE

[[2]]
[1] 
FALSE TRUE

[[3]]
[1]
FALSE

[[4]]
[1]
FALSE

[[5]]
[1] 
FALSE FALSE TRUE

Если я попытаюсь применить m1[1]==m3[1] или подобное, я получу сообщения как Error in m1 == m3 : comparison of these types is not implemented. Мне не удается сделать эту простую вещь! Заранее благодарим за помощь.

Ответы [ 3 ]

2 голосов
/ 27 мая 2020

Вы можете использовать Map (или mapply) с %in%.

Map(`%in%`, m1, m3)

[[1]]
logical(0)

[[2]]
[1] FALSE  TRUE

[[3]]
logical(0)

[[4]]
[1] FALSE

[[5]]
[1] FALSE FALSE  TRUE

Однако m1 содержит integer(0), что делает %in% return logical(0) вместо FALSE. Поэтому вам нужно преобразовать logical(0) в FALSE после этого.

res <- Map(`%in%`, m1, m3)
res[lengths(res) == 0] <- FALSE
res

[[1]]
[1] FALSE

[[2]]
[1] FALSE  TRUE

[[3]]
[1] FALSE

[[4]]
[1] FALSE

[[5]]
[1] FALSE FALSE  TRUE
2 голосов
/ 27 мая 2020

И Даррен, и EJJ решили использовать go и использовать %*%

Если мы не возражаем против поведения NA по умолчанию при логическом сравнении, мы можем использовать простые for-loop или lapply

lapply(seq(la), function(i)a[[i]] == b[[i]])

Если мы хотим обеспечить некоторую безопасность, чтобы списки были «сопоставимы», мы можем сравнить их внешнюю и внутреннюю длину и обернуть это в функцию, как показано ниже

compare_each_list_element <- function(a, b){
  la <- length(lla <- lengths(a))
  lb <- length(llb <- lengths(b))
  if(la != lb || any(lla != llb)){
    warning('Either length(a) != length(b) or some length within a is not equal to some length within b!')
    return(FALSE)
  }
  lapply(seq(la), function(i)a[[i]] == b[[i]])
}
compare_each_list_element(list(1:3, 2, c(3, 2)), list(1:3, 3, c(2, NA)))
[[1]]
[1] TRUE TRUE TRUE

[[2]]
[1] FALSE

[[3]]
[1] FALSE    NA
1 голос
/ 27 мая 2020

Вы можете попробовать использовать библиотеку purrr для получения желаемого результата, в которой исследуется каждый элемент. Я использовал %in% вместо ==, если NAs существует. Также предполагается, что каждый список имеет одинаковую структуру для работы.

library(purrr)
purrr::map2(m1, m3, function(x, y) x %in% y)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...