2016-03-29 56 views
3

我有這樣一個data.table:矢量化:如何才能在向量矢量中只有所有元素集合的集合差異?

dt=data.table(freq=c(4,3,2,1),elements=list(c('a','b','c'), 
              c('a','d'), 
              c('b','d'), 
              c('b','d','c','e'))) 
    freq elements 
1: 4 a,b,c 
2: 3  a,d 
3: 2  b,d 
4: 1 b,d,c,e 

我需要每一行中的元素是隻有該行的元素和該行之前的集合中的所有元素的關節之間的差集。這樣一來,我會得到這樣的:

freq elements 
1: 4 a,b,c 
2: 3  d 
3: 2  NA 
4: 1  e 

我可以與該組中的所有元素做到這一點,直到我-1,只得到差集,但我真的想知道如何做到這一點的矢量化的方式,如果可能的話。

謝謝你們!

+6

你怎麼' e'在最後一行? – akrun

+0

另外,如果你有一個非矢量化的解決方案,它是什麼? – Justin

+1

也許你可以找到每個元素和累積集合的集合差異?例如。 'Map(setdiff,dt $ elements,head(Reduce(union,dt $ elements,accumulate = TRUE,init = NULL),-1L))' –

回答

8

假設你的意思是有dt你的最後一排的一個「e」,那freq是唯一的(如果沒有,創建唯一索引,或者用行):

dt[, .(els = elements[[1]]), by = freq][ 
    , .(freq = freq[1]), by = els][ 
    , .(filtered = list(els)), by = freq][ 
    dt, on = 'freq'] 
# freq filtered elements 
#1: 4 a,b,c a,b,c 
#2: 3  d  a,d 
#3: 2  NULL  b,d 
#4: 1  e b,d,e 
+0

謝謝Eddi,非常好的回答,我只是不明白你剛纔寫的算法的流程,你能幫我理解嗎? –

+0

@AldoPareja嘗試增量運行它(每次添加一組[] s) - 這個想法很簡單 - 找到每個元素的第一個freq(上面的第二行) - 其餘的只是按照您喜歡的格式重新排列它 – eddi

+0

哦,我現在明白了....非常感謝你! –