3

感谢您对我之前的问题的友好回复。我有两个列表:list1 和 list2。我想知道list1的每个对象是否包含在list2的每个对象中。例如:

> list1
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

> list2
[[1]]
[1] 1 2 3

[[2]]
[1] 2 3

[[3]]
[1] 2 3

以下是我的问题: 1.) 我如何让 R 检查一个对象是否是列表中另一个对象的子集?例如,我想检查是否list2[[3]]={2,3}包含在 (subset of) 中list1[[2]]={2}。当我这样做时list2[[3]] %in% list1[[2]],我得到了[1] TRUE FALSE。然而,这不是我想要做的吗?!我只想检查是否list2[[3]]是 的子集list1[[2]],即 {2,3} \subset of {3} 是否如集合论概念中的那样?我不想执行元素检查,因为 R 似乎正在使用 %in% 命令。有什么建议么?

2.) 是否有某种方法可以有效地进行所有成对子集比较(即,对于所有组合的子集?一旦第 1 个问题得到回答,类似list1[[i]]的方法会起作用吗?谢谢您的反馈!list2[[j]]i,jouter(list1,list2, func.subset)

4

4 回答 4

5

setdiff比较唯一

length(setdiff(5, 1:5)) == 0

或者,all(x %in% y)会很好地工作。

要进行所有比较,这样的事情会起作用:

dt <- expand.grid(list1,list2)
dt$subset <- apply(dt,1, function(.v) all(.v[[1]] %in% .v[[2]]) )


  Var1    Var2 subset
1    1 1, 2, 3   TRUE
2    2 1, 2, 3   TRUE
3    3 1, 2, 3   TRUE
4    1    2, 3  FALSE
5    2    2, 3   TRUE
6    3    2, 3   TRUE
7    1    2, 3  FALSE
8    2    2, 3   TRUE
9    3    2, 3   TRUE

请注意,expand.grid在处理大量数据时,这并不是最快的方法(dwin 的解决方案在这方面更好),但它允许您快速直观地检查这是否符合您的要求。

于 2013-01-19T01:10:04.617 回答
2

您可以sets按如下方式使用该软件包:

library(sets)
is.subset <- function(x, y) as.set(x) <= as.set(y)

outer(list1, list2, Vectorize(is.subset))
#      [,1]  [,2]  [,3]
# [1,] TRUE FALSE FALSE
# [2,] TRUE  TRUE  TRUE
# [3,] TRUE  TRUE  TRUE

@Michael 或@DWin 的基本版本也is.subset可以正常工作,但是对于您问题的第二部分,我认为这outer是要走的路。

于 2013-01-19T01:50:10.897 回答
1
is.subset <- function(x,y) {length(setdiff(x,y)) == 0}

首先是作为 list2 项子集的 list1 元素的组合:

> sapply(1:length(list1), function(i1) sapply(1:length(list2), 
                 function(i2) is.subset(list1[[i1]], list2[[i2]]) ) )
      [,1] [,2] [,3]
[1,]  TRUE TRUE TRUE
[2,] FALSE TRUE TRUE
[3,] FALSE TRUE TRUE

然后不出所料地缺少任何作为列表一项目子集的列表 2 项目(所有长度 > 1)(长度均为 1):

> sapply(1:length(list1), function(i1) sapply(1:length(list2), 
                 function(i2) is.subset(list2[[i2]], list1[[i1]]) ) )
      [,1]  [,2]  [,3]
[1,] FALSE FALSE FALSE
[2,] FALSE FALSE FALSE
[3,] FALSE FALSE FALSE
于 2013-01-19T01:35:09.520 回答
0

添加到@Michael's,这是使用 AsIs 函数避免 expand.grid 混乱的一种巧妙方法:

list2 <- list(1:3,2:3,2:3)
a <- data.frame(list1 = 1:3, I(list2))
a$subset <- apply(a, 1, function(.v) all(.v[[1]] %in% .v[[2]]) )

  list1   list2 subset
1     1 1, 2, 3   TRUE
2     2    2, 3   TRUE
3     3    2, 3   TRUE
于 2017-09-26T02:03:54.527 回答