简体   繁体   English

从列表中删除出现在R中另一个子元素列表中的子元素

[英]Removing subelements from a list which appear in another subelements list in R

I have two lists of matrix 我有两个矩阵列表

lst1 <- lapply(1:4, function(i) combn(x=4,m=i))
lst2 <- lapply(1:5, function(i) combn(x=5,m=i))

and would like to extract the columns for matrix in the 2nd list that is not in the columns of matrix in the first list. 并希望提取第二个列表中矩阵的列,而不是第一个列表中矩阵的列。 Can you help please? 你能帮忙吗?

eg 例如

I would like to get this list below 我想在下面得到这个清单

[[1]]
     [,5]
[1,]    5

[[2]]
     [,4] [,7] [,9] [,10]
[1,]    1    2    3     4
[2,]    5    5    5     5

[[3]]
    [,3] [,5] [,6] [,8] [,9] [,10]
[1,]   1    1    1    2    2     3
[2,]   2    3    4    3    4     4
[3,]   5    5    5    5    5     5

[[4]]
    [,2] [,3] [,4] [,5]
[1,]   1    1    1    2
[2,]   2    2    3    3
[3,]   3    4    4    4
[4,]   5    5    5    5

[[5]]
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5

How about the following 接下来呢

lapply(lst2, function(x) Filter(Negate(is.null), lapply(lst1, function(y)
    if (nrow(x) == nrow(y)) x[, !apply(x, 2, toString) %in% apply(y, 2, toString)])))
#[[1]]
#[[1]][[1]]
#[1] 5
#
#
#[[2]]
#[[2]][[1]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    2    3    4
#[2,]    5    5    5    5
#
#
#[[3]]
#[[3]][[1]]
#     [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]    1    1    1    2    2    3
#[2,]    2    3    4    3    4    4
#[3,]    5    5    5    5    5    5
#
#
#[[4]]
#[[4]][[1]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    1    1    2
#[2,]    2    2    3    3
#[3,]    3    4    4    4
#[4,]    5    5    5    5
#
#
#[[5]]
#list()

For every entry in lst2 we check for unique columns from all entries in lst1 . 对于lst2每个条目,我们检查lst1所有条目的唯一列。 Therefore the length of the output list equals the length of lst2 , which makes it easy to identify entries from lst2 that have no unique columns with any entry from lst1 (as is the case for the fifth entry from lst2 ). 因此,输出list的长度等于lst2的长度,这使得从lst2轻松识别没有唯一列且lst1没有任何条目的条目(与lst2的第五个条目一样)。


Update 更新资料

To exactly reproduce your expected output you can do 完全重现您的预期输出,您可以执行

lst <- lapply(lst2, function(x) Filter(Negate(is.null), lapply(lst1, function(y)
    if (nrow(x) == nrow(y)) x[, !apply(x, 2, toString) %in% apply(y, 2, toString)])))

lst <- unlist(lapply(seq_along(lst), function(i)
    if (length(lst[[i]]) == 0) lst[[i]] <- list(lst2[[i]]) else lst[[i]]), recursive = F)
lst;
#[[1]]
#[1] 5
#
#[[2]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    2    3    4
#[2,]    5    5    5    5
#
#[[3]]
#     [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]    1    1    1    2    2    3
#[2,]    2    3    4    3    4    4
#[3,]    5    5    5    5    5    5
#
#[[4]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    1    1    2
#[2,]    2    2    3    3
#[3,]    3    4    4    4
#[4,]    5    5    5    5
#
#[[5]]
#     [,1]
#[1,]    1
#[2,]    2
#[3,]    3
#[4,]    4
#[5,]    5

Using Base R: 使用Base R:

Map(function(x,y)as.matrix(unname(setdiff(data.frame(y),data.frame(x)))),c(lst1,NA),lst2) 

[[1]]
  [,1]
1    5

[[2]]
  [,1] [,2] [,3] [,4]
1    1    2    3    4
2    5    5    5    5

[[3]]
  [,1] [,2] [,3] [,4] [,5] [,6]
1    1    1    1    2    2    3
2    2    3    4    3    4    4
3    5    5    5    5    5    5

[[4]]
  [,1] [,2] [,3] [,4]
1    1    1    1    2
2    2    2    3    3
3    3    4    4    4
4    5    5    5    5

[[5]]
  [,1]
1    1
2    2
3    3
4    4
5    5

or you can do 或者你可以做

purrr::map2(c(lst1,NA),lst2,~as.matrix(unname(setdiff(data.frame(.y),data.frame(.x)))))

[[1]]
     [,1]
[1,]    5

[[2]]
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    5    5    5

[[3]]
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    1    2    2    3
[2,]    2    3    4    3    4    4
[3,]    5    5    5    5    5    5

[[4]]
     [,1] [,2] [,3] [,4]
[1,]    1    1    1    2
[2,]    2    2    3    3
[3,]    3    4    4    4
[4,]    5    5    5    5

[[5]]
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5

Here is another base R option 这是另一个base R选项

fpaste <- function(x) tapply(x, col(x), toString)
fun1 <- Vectorize(function(x, y) x[,!fpaste(x) %in% fpaste(y), drop = FALSE])
m1 <- outer(lst2, lst1, FUN = fun1)
c(diag(m1), m1[length(m1)])
#[[1]]
#     [,1]
#[1,]    5

#[[2]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    2    3    4
#[2,]    5    5    5    5

#[[3]]
#     [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]    1    1    1    2    2    3
#[2,]    2    3    4    3    4    4
#[3,]    5    5    5    5    5    5

#[[4]]
#     [,1] [,2] [,3] [,4]
#[1,]    1    1    1    2
#[2,]    2    2    3    3
#[3,]    3    4    4    4
#[4,]    5    5    5    5

#[[5]]
#     [,1]
#[1,]    1
#[2,]    2
#[3,]    3
#[4,]    4
#[5,]    5

This should work: 这应该工作:

foo  <-  function(z,w) w[,!apply(matrix(apply(w,2,function(y) apply(z, 2, 
function(x) identical(x, y))), nrow=ncol(z)),2,any)]

mapply(foo, lst1,lst2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM