2014-12-16 17 views
6

Chcę mieć przecięcie wszystkich grup tabeli danych. Więc dla danego dane:R data.table przecięcie wszystkich grup

data.table(a=c(1,2,3, 2, 3,2), myGroup=c("x","x","x", "y", "z","z")) 

chcę mieć wynik:

2 

wiem że

Reduce(intersect, list(c(1,2,3), c(2), c(3,2))) 

da mi pożądany wynik, ale nie zorientować się, jak utworzyć listę grup zapytania data.table.

Odpowiedz

5

chciałbym spróbować użyć Reduce w następujący sposób (zakładając dt jest dane)

Reduce(intersect, dt[, .(list(unique(a))), myGroup]$V1) 
## [1] 2 
+1

Podoba mi się. Jest to prostsze, łatwiejsze do zrozumienia i zdecydowanie bardziej zgodne z podejściem stosowanym przez OP. –

2

Oto jedno podejście.

nGroups <- length(unique(dt[,myGroup])) 
dt[, if(length(unique(myGroup))==nGroups) .BY else NULL, by="a"][[1]] 
# [1] 2 

A oto kilka uwag wyjaśniających.

## Mark down the number of groups in your data set 
nGroups <- length(unique(dt[,myGroup])) 
## Then, use `by="a"` to examine in turn subsets formed by each value of "a". 
## For subsets having the full complement of groups 
## (i.e. those for which `length(unique(myGroup))==nGroups)`, 
## return the value of "a" (stored in .BY). 
## For the other subsets, return NULL. 
dt[, if(length(unique(myGroup))==nGroups) .BY else NULL, by="a"][[1]] 
# [1] 2 

Jeśli ten kod i komentarze nie są jednoznaczne, pomocne może się okazać szybkie spojrzenie na poniższe. Zasadniczo powyższe podejście polega jedynie na szukaniu i zgłaszaniu wartości a dla grup, które zwracają x,y,z w kolumnie V1 poniżej.

dt[,list(list(unique(myGroup))), by="a"] 
# a V1 
# 1: 1  x 
# 2: 2 x,y,z 
# 3: 3 x,z 
+0

Up-głosowało ale logika pozostaje nieprzejrzysty do mnie. –

+0

@BondedDust - OK, dodano wyjaśnienie. –