2013-01-07 43 views
2

大家好,新年快樂, 我想知道如果data.table可以處理基於每個分組的選擇執行的更新。內更新和下降

R) a=data.table(x=c("a","a","b","b","c","c"),y=c(1,2,3,3,2,1)) 
R) a 
    x y 
1: a 1 
2: a 2 
3: b 3 
4: b 3 
5: c 2 
6: c 1 

如果我想通過每一個組,我需要做的選擇在j內一個條件更新,但是這更多的i事(選擇)。

R) a[,c:=ifelse(y==max(y),"yes","no"),by=x] 
R) a 
    x y c 
1: a 1 no 
2: a 2 yes 
3: b 3 yes 
4: b 3 yes 
5: c 2 yes 
6: c 1 no 

可以使用選項類似a[y==max(y),c:="yes",by=x,within.by=TRUE]我認爲這將是更快

第二個問題,是不是定得下降的說法我做同樣的data.table,要能夠做到 DT[drop="x,y,z"]那本質上是DT[,':='(x=NULL,y=NULL,z=NULL)]

+0

請勿使用'ifelse'。 'a [,c:= y == max(y),by = x]'更快。 – Roland

+0

夠公平的,但我需要2行 – statquant

+2

您不需要兩行:'a [,c:= c(「no」,「yes」)[(y == max(y))+ 1],by = X]'。 –

回答

1

這只是一個猜測,關注和建立在評論上:which.max(x)可能會比x==max(x)更快。

?which.max

which.min價值和which.max
長度爲1或0的整數(當且僅當x具有沒有非NAS),分別給予所述第一最小值或最大值的索引X。如果這個極值是唯一的(或爲空),結果分別與which(x == min(x))which(x == max(x))相同(但效率更高)。

所以,也許是這樣的:

DT[,c:="no"] 
w = DT[,list(IDX=.I[which.max(y)]),by=x]$IDX 
DT[w,c:="yes"] 

使用i這可能是你在說什麼。結果w只是每個組的一個項目,而不是每個組的.N,所以它也可能因爲這個原因而更快。不僅僅是which.max本身。但是,當然如果最大值可以被綁定,那麼which.max將只返回第一個,所以根據您的數據可能不合適。

如果您進行基準測試,請確保將數據設置爲較大(1GB +),並將keyed by與未使用的key進行比較。

+0

感謝@ user1935457爲您的更正添加'.I'。不知道爲什麼其他人拒絕了,但我現在已經包括了它。 –

+0

謝謝,我從這篇文章中學到了東西,讓我們來關閉它。 – statquant