删除列表中其他向量的子集的向量

时间:2017-03-28 18:34:27

标签: r

我有一个不同长度的矢量列表,例如:

a=c(12345,12367,91670,87276,92865)
b=c(12345,87276,89250)
c=c(12367,91670)
d=c(23753,82575,91475,10957,92865,24311)
mylist=list(a,b,c,d)
mylist

# [[1]]
# [1] 12345 12367 91670 87276 92865
# 
# [[2]]
# [1] 12345 87276 89250
# 
# [[3]]
# [1] 12367 91670
# 
# [[4]]
# [1] 23753 82575 91475 10957 92865 24311

我的问题是如何删除此列表的向量,这些向量是同一列表中另一个向量的子集。即在这种情况下,如何删除列表中的第3个对象?第3个对象是第1个对象的子集?

5 个答案:

答案 0 :(得分:3)

这可能效率很低,但如果你的列表不是那么大,那就可以了。

find_nested <- function(mylist) {
    mm <- sapply(mylist, function(x) sapply(mylist, function(y) all(x %in%y)))
    diag(mm) <- FALSE
    apply(mm,2,any)
}

这可以告诉你哪些向量是其他向量的子集。它通过将每个向量与每个其他向量进行比较来实现此目的。

find_nested(mylist)
# [1] FALSE FALSE  TRUE FALSE

所以我们可以看到第三个项目包含在另一个列表中。

答案 1 :(得分:2)

which(t(sapply(seq_along(mylist), function(i)
    sapply(mylist[-i], function(a)
        all(unlist(mylist[i]) %in% a)))), arr.ind = TRUE)
#     row col
#[1,]   3   1
#Suggests that 3rd item is contained within 1st item

答案 2 :(得分:2)

这给出了一个没有其他子集的元素的新列表......

newlist <- mylist[!sapply(seq_along(mylist), function(i) max(sapply(mylist[-i],function(L) all(mylist[[i]] %in% L))))]

答案 3 :(得分:1)

这是另一种方法。它也不是超级高效,但会返回嵌套列表的位置。

#pragma once

#include <windows.h>

#define OPERATION_EXIT_THREAD 1
#define OPERATION_START_WRITING_NAME 2

struct Sync
{
    CONDITION_VARIABLE canWork;
    CONDITION_VARIABLE isEndWork;
    HANDLE threadHandle;        //handle to thread
    int operation;              //operation type: 1 - exit, 2 - start writing name
    int index;                  //thread index

    Sync()
    {
        InitializeConditionVariable(&canWork);
        InitializeConditionVariable(&isEndWork);
        threadHandle = NULL;
        operation = 0;
        index = -1;
    }

    ~Sync()
    {
        if (threadHandle)
        {
            CloseHandle(threadHandle);
        }
    }
};

有序很重要,因为比较不对称。现在,循环使用这些组合并使用# get ordered pairwise combinations of list positions combos <- combn(1:4, 2) combos <- cbind(combos, combos[2:1,]) 比较集。

intersect

重写最后一行以使用combos[1, sapply(seq_len(ncol(combos)), function(i) setequal(intersect(mylist[[combos[1,i]]], mylist[[combos[2,i]]]), mylist[[combos[1,i]]]))] [1] 3 而不是mapply可能会提高可读性。

sapply

答案 4 :(得分:1)

元素的替代(&#34; list&#34;)格式是&#34;元素依值&#34;的表格:

table(values = unlist(mylist), 
      elt = rep(seq_along(mylist), lengths(mylist)))
#       elt
#values  1 2 3 4
#  10957 0 0 0 1
#  12345 1 1 0 0
#  12367 1 0 1 0
#  23753 0 0 0 1
#  24311 0 0 0 1
#  82575 0 0 0 1
#  87276 1 1 0 0
#  89250 0 1 0 0
#  91475 0 0 0 1
#  91670 1 0 1 0
#  92865 1 0 0 1

这很容易消耗大量内存,因此我们可以追逐稀疏的替代方案:

l = unlist(mylist)
ul = unique(l)
tab = sparseMatrix(x = TRUE, 
                   i = match(l, ul), 
                   j = rep(seq_along(mylist), lengths(mylist)), 
                   dimnames = list(ul, sprintf("elt_%d", seq_along(mylist))))

tab
#11 x 4 sparse Matrix of class "lgCMatrix"
#      elt_1 elt_2 elt_3 elt_4
#12345     |     |     .     .
#12367     |     .     |     .
#91670     |     .     |     .
#87276     |     |     .     .
#92865     |     .     .     |
#89250     .     |     .     .
#23753     .     .     .     |
#82575     .     .     .     |
#91475     .     .     .     |
#10957     .     .     .     |
#24311     .     .     .     |

然后,找出哪个元素是其中的一个子集:

subsets = lengths(mylist) == crossprod(tab)

subsets
#4 x 4 sparse Matrix of class "lgCMatrix"
#      elt_1 elt_2 elt_3 elt_4
#elt_1     |     .     .     .
#elt_2     .     |     .     .
#elt_3     |     .     |     .
#elt_4     .     .     .     |

其中,每个元素都是...本身的子集,3是1的子集。要获得我们可以使用的有用信息:

subset(summary(subsets), i != j)[c("i", "j")]

# 
#  i j
#2 3 1 

或者,为了避免加入&#34; diag&#34;之后,我们可以操纵已经存在的结构:

dp = diff(subsets@p)
j = rep(0:(length(dp) - 1), dp)
wh = subsets@i != j
cbind(subset = subsets@i[wh], of = j[wh]) + 1L
#     subset of
#[1,]      3  1

在最后两种情况下,第一列的unique显示哪些元素是另一个元素的子集,可以用于[&#34; mylist&#34;。