2016-02-12 61 views
8

不知道如何用文字形式表達問題,但是如何在出現不同值時爲每個組遞增的data.table創建索引列?data.table中的索引唯一值

這裏是MWE

library(data.table) 
in.data <- data.table(fruits=c(rep("banana", 4), rep("pear", 5)),vendor=c("a", "b", "b", "c", "d", "d", "e", "f", "f")) 

這裏是R-代碼應該生成

in.data[, wanted.column:=c(1,2,2,3,1,1,2,3,3)] 

# fruits vendor wanted.column 
# 1: banana  a    1 
# 2: banana  b    2 
# 3: banana  b    2 
# 4: banana  c    3 
# 5: pear  d    1 
# 6: pear  d    1 
# 7: pear  e    2 
# 8: pear  f    3 
# 9: pear  f    3 

所以標註每個供應商1,2,3時,結果...每個水果內。可能有一個非常簡單的解決方案,但我卡住了。

+1

它的工作!我像這樣添加它:in.data [,wanted.2:= in.data [,rleid(vendor),by = fruits] [,V1]]。也許你可以寫一個答案,以便我可以接受它? – Chris

回答

9

我有幾點想法。您可以使用嵌套組計數器:

in.data[, w := setDT(list(v = vendor))[, g := .GRP, by=v]$g, by=fruits] 

或者,使運行ID,這取決於排序的數據(感謝@eddi),似乎浪費:

in.data[, w := rleid(vendor), by=fruits] 

基礎-R的做法可能會是:

in.data[, w := match(vendor, unique(vendor)), by=fruits] 

# or in base R ... 

in.data$w = with(in.data, ave(vendor, fruits, FUN = function(x) match(x, unique(x)))) 
+1

謝謝!我永遠無法自己解決它。 – Chris

+1

值得注意的是,如果你做了第一個和第二個選項,就會產生不同的結果。 'in.data [6,vendor:='f']'。我不確定哪一個是理想的結果。 – eddi

+0

好點;謝謝@eddi – Frank

8

另一種方法可能有兩個步驟:

DT = data.table(fruits=c(rep("banana", 4), rep("pear", 5)),vendor=c("a", "b", "b", "c", "d", "d", "e", "f", "f")) 
DT 
    fruits vendor 
1: banana  a 
2: banana  b 
3: banana  b 
4: banana  c 
5: pear  d 
6: pear  d 
7: pear  e 
8: pear  f 
9: pear  f 
DT[, wanted:=.GRP, by="fruits,vendor"] # step 1 
DT 
    fruits vendor wanted 
1: banana  a  1 
2: banana  b  2 
3: banana  b  2 
4: banana  c  3 
5: pear  d  4 
6: pear  d  4 
7: pear  e  5 
8: pear  f  6 
9: pear  f  6 
DT[, wanted:=wanted-wanted[1]+1L, by="fruits"] # step 2 (adjust) 
DT 
    fruits vendor wanted 
1: banana  a  1 
2: banana  b  2 
3: banana  b  2 
4: banana  c  3 
5: pear  d  1 
6: pear  d  1 
7: pear  e  2 
8: pear  f  3 
9: pear  f  3 
> 

我會在生產代碼註釋這個問題的方法可能是:

DT[, wanted:=.GRP, by="fruits,vendor"]   # .GRP is simple group counter 
DT[, wanted:=wanted-wanted[1]+1L, by="fruits"] # reset vendor counter per fruit 
+0

謝謝。我在生產中使用R,所以感謝這方面的例子。 data.table對我來說仍然很神奇,但我希望最終能夠理解它。 – Chris

+1

@Chris很高興聽到。似乎你到達那裏。很高興看到一個好的MRE。 –

+2

@Chris雖然你的MRE留下了一些模棱兩可的問題,這引起了困惑。通過納入不相鄰的團體並說出期望的結果,MRE本來可以更好。 –

4

如果您想要索引對於給定的水果中的所有廠商相同,那麼這是另一種選擇:

in.data[, wanted := as.integer(factor(vendor, levels = unique(vendor))), by = fruits] 

否則,如果您希望每次供應商更改時都打勾,那麼從給出的答案到目前爲止,rleid是唯一有效的。