我有一份清单:
x <- list("a" = c(1:6,32,24) , "b" = c(1:4,8,10,12,13,17,24),
"F" = c(1:5,9:15,17,18,19,20,32))
x
$a
[1] 1 2 3 4 5 6 32 24
$b
[1] 1 2 3 4 8 10 12 13 17,24
$F
[1] 1 2 3 4 5 9 10 11 12 13 14 15 17 18 19 20 32列表中的每个向量与其他向量共享一些元素。如何删除共享值以获得以下结果?
$a
[1] 1 2 3 4 5 6 32 24
$b
[1] 8 10 12 13 17
$F
[1] 9 11 14 15 18 19 20正如你所看到的:第一个向量不会改变。第一向量和第二向量之间的共享元素将从第二向量中删除,然后与第一和第二向量进行比较后,将共享元素从第三向量中删除。此任务的目标是集群数据集(原始数据集包含590个对象)。
发布于 2017-09-27 11:56:09
x <- list("a" = c(1:6,32,24) ,
"b" = c(1:4,8,10,12,13,17,24),
"F" = c(1:5,9:15,17,18,19,20,32))这是低效的,因为它会在每一步重新组合上一组列表(而不是保持一个运行的总数),但这是我首先想到的方法。
for (i in 2:length(x)) {
## construct union of all previous lists
prev <- Reduce(union,x[1:(i-1)])
## remove shared elements from the current list
x[[i]] <- setdiff(x[[i]],prev)
} 您可能可以通过将prev初始化为numeric(0)并在每一步将prev转化为c(prev,x[i-1])来改进这一点(尽管每一步都会生成一个向量,这是一个缓慢的操作)。如果你没有一个庞大的数据集/不需要做这个操作数百万次,它可能就足够好了。
发布于 2017-09-27 12:07:37
您可以使用列表中的Reduce和setdiff逆序查找最后一个向量中没有出现在其他向量中的所有元素。将其放入lapply以运行部分子列表以获得所需的输出:
lapply(seq_along(x), function(y) Reduce(setdiff,rev(x[seq(y)])))
[[1]]
[1] 1 2 3 4 5 6 32 24
[[2]]
[1] 8 10 12 13 17
[[3]]
[1] 9 11 14 15 18 19 20当扩展时,rev调用的数量可能会成为一个问题,因此您可能希望将列表反转一次,在lapply之外作为一个新变量,以及其中的子集。
https://stackoverflow.com/questions/46447142
复制相似问题