【问题标题】:How can I remove shared values from a list of vectors如何从向量列表中删除共享值
【发布时间】:2018-03-08 21:33:52
【问题描述】:

我有一个清单:

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

【问题讨论】:

    标签: r list vector


    【解决方案1】:

    您可以在列表中以相反的顺序使用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 之外作为一个新变量,并在其中设置子集。

    【讨论】:

    • x_rev
    • @AndreElrico 好点,您必须注意索引。我认为tail(x_rev,y) 效果最好。
    【解决方案2】:
    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]) 来改进这一点(尽管这在每一步都会增长一个向量,这是一个缓慢的操作)。如果您没有庞大的数据集/不必执行此操作数百万次,这可能就足够了。

    【讨论】:

      猜你喜欢
      • 2015-01-03
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      相关资源
      最近更新 更多