2017-03-06 153 views
4

我想刪除其中列表的其他部分的完整集合的列表的一部分。例如,B相交A和E相交C,因此B和E應該被移除。刪除列表中的元素R

MyList <- list(A=c(1,2,3,4,5), B=c(3,4,5), C=c(6,7,8,9), E=c(7,8)) 
MyList 
$A 
[1] 1 2 3 4 5 
$B 
[1] 3 4 5 
$C 
[1] 6 7 8 9 
$E 
[1] 7 8 

MyListUnique <- RemoveSubElements(MyList) 
MyListUnique 
$A 
[1] 1 2 3 4 5 
$C 
[1] 6 7 8 9 

任何想法?任何知道這樣做的函數?

+0

如果效率是不是一個問題,也許'IDX < - (!expand.grid(seq_along(MYLIST),seq_along(MYLIST)),VAR1 = VAR2)子集 REM < - 唯一(的名稱( (長度(mapply(setdiff,MyList [idx [,1]],MyList [idx [,2]]))== 0))) MyList [!names(MyList)%in%rem]'。 – lukeA

+0

用'tmp = crossprod(table(stack(MyList)))'或者一個稀疏的選項開始可能會更方便。例如,在這種情況下,'tmp&(diag(tmp)[col(tmp)] - tmp)'似乎正確指出哪些(行)是其中的一部分(列)(即'rownames(which &(diag(tmp)[col(tmp)] - tmp),TRUE))'似乎在這裏工作)。你能否提供更多關於這個問題的背景/案例? –

回答

1

只要你的數據是不是過於龐大,可以使用如下的方法:

# preparation 
MyList <- MyList[order(lengths(MyList))] 
idx <- vector("list", length(MyList)) 
# loop through list and compare with other (longer) list elements 
for(i in seq_along(MyList)) { 
    idx[[i]] <- any(sapply(MyList[-seq_len(i)], function(x) all(MyList[[i]] %in% x))) 
} 
# subset the list 
MyList[!unlist(idx)]   
#$C 
#[1] 6 7 8 9 
# 
#$A 
#[1] 1 2 3 4 5 
1

類似於其他答案,但希望更清晰,使用輔助功能和2 sapply秒。

#helper function to determine a proper subset - shortcuts to avoid setdiff calculation if they are equal 
is.proper.subset <- function(x,y) !setequal(x,y) && length(setdiff(x,y))==0 

#double loop over the list to find elements which are proper subsets of other elements 
idx <- sapply(MyList, function(x) any(sapply(MyList, function(y) is.proper.subset(x,y)))) 

#filter out those that are proper subsets 
MyList[!idx] 
$A 
[1] 1 2 3 4 5 

$C 
[1] 6 7 8 9