如何从向量列表中删除共享值

时间:2017-09-27 11:50:30

标签: r list vector

我有一个清单:

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个对象)。

2 个答案:

答案 0 :(得分:5)

您可以按相反的顺序在列表中使用Reducesetdiff,以查找最后一个矢量中未出现在其他元素中的所有元素。将其加入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之外作为新变量,以及其中的子集。< / p>

答案 1 :(得分:1)

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])来改善这一点(尽管这会在每一步增加一个向量,这是一个运行缓慢)。如果您没有庞大的数据集/不必进行数百万次此操作,那么它可能已经足够好了。

相关问题