我有一个不同长度的矢量列表,例如:
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个对象的子集?
答案 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;。