[英]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
的第五个条目一样)。
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.