如何删除共享值
问题描述:
我有一个列表:如何删除共享值
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个对象)。
答
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])
在每一步(虽然这种增长在每一个步骤,这是一个缓慢的操作的矢量)改进这一点。如果你没有一个巨大的数据集/不必做数百万次这个操作就可能足够好。
答
,可以在列表上使用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
以及其中的子集。
x_rev
谢谢,詹姆斯为你的答案,它完美的作品。 – Noor
@AndreElrico好点,你必须注意索引。我认为'tail(x_rev,y)'会效果最好。 – James