2016-01-09 33 views
2

我想獲取data.table中一組變量的唯一出現次數列表。以下代碼有效。 我只是想知道是否有可能推廣一個函數。它可能對中等規模的數據具有更普遍的適用性。獲取data.table中一組變量的唯一出現次數列表

packageVersion('data.table') 
[1] ‘1.9.7’ 
library(data.table) 
DT <- data.table(x1=c("b","c", "a", "b", "a", "b",'b'), x2=as.character(c(1:6,1)),m1=c(seq(10,60,by=10),10),m2=1:7) 
DT 
> DT 
    x1 x2 m1 m2 
1: b 1 10 1 
2: c 2 20 2 
3: a 3 30 3 
4: b 4 40 4 
5: a 5 50 5 
6: b 6 60 6 
7: b 1 10 7 

###get unique counts of each occurrence of first variable x1 
setkey(DT,x1) 
u1<-DT[,.(uN1=uniqueN(.SD)),by=x1] 
U1<-u1[DT] 
U1 
> U1 
    x1 uN1 x2 m1 m2 
1: a 2 3 30 3 
2: a 2 5 50 5 
3: b 4 1 10 1 
4: b 4 4 40 4 
5: b 4 6 60 6 
6: b 4 1 10 7 
7: c 1 2 20 2 

###unique counts of (x1,x2) 
setkey(U1,x1,x2) 
u2<-U1[,.(uN2=uniqueN(.SD)),by=.(x1,x2)] 
U2<-u2[U1] 
U2 
> U2 
    x1 x2 uN2 uN1 m1 m2 
1: a 3 1 2 30 3 
2: a 5 1 2 50 5 
3: b 1 2 4 10 1 
4: b 1 2 4 10 7 
5: b 4 1 4 40 4 
6: b 6 1 4 60 6 
7: c 2 1 1 20 2 

###unique counts of (x1,x2,m1) 
setkey(U2,x1,x2,m1) 
u3<-U2[,.(uN3=uniqueN(.SD)),by=.(x1,x2,m1)] 
U3<-u3[U2] 
# desired order 
setcolorder(U3,c('x1','uN1','x2','uN2','m1','uN3','m2')) 
U3 
> U3 
    x1 uN1 x2 uN2 m1 uN3 m2 
1: a 2 3 1 30 1 3 
2: a 2 5 1 50 1 5 
3: b 4 1 2 10 2 1 
4: b 4 1 2 10 2 7 
5: b 4 4 1 40 1 4 
6: b 4 6 1 60 1 6 
7: c 1 2 1 20 1 2 

所提出的功能可以是這樣的:

UniqueCombN(DT, listX) 

其中listX是在數據表中感興趣的變量列表。

+2

只是使用'DT [,UN1:= uniqueN(.SD),X1] [,UN2:= uniqueN(。 SD),。(x1,x2)] [,uN3:= uniqueN(.SD),。(x1,x2,m1)]'會給你相同的結果。 – Jaap

+0

@Jaap您的建議似乎正是我所期待的。除了列排序。但是這可以很容易地解決。 – Vivek

+0

@Jaap讓我們繼續嘗試回答這個問題,讓他們沒有在未答覆的列表中列出,如果你不打算,你可以建議讓Vivek自己編寫代碼。 – jangorecki

回答

2

您使用的幾個連接是不需要的。您可以通過參考與更新data.table達到同樣的效果:

DT[, uN1:=uniqueN(.SD), x1 
    ][, uN2:=uniqueN(.SD), .(x1,x2) 
    ][, uN3:=uniqueN(.SD), .(x1,x2,m1)] 

給出:

> DT 
    x1 x2 m1 m2 uN1 uN2 uN3 
1: b 1 10 1 4 2 2 
2: c 2 20 2 1 1 1 
3: a 3 30 3 2 1 1 
4: b 4 40 4 4 1 1 
5: a 5 50 5 2 1 1 
6: b 6 60 6 4 1 1 
7: b 1 10 7 4 2 2 

如果你想設置的順序,可以使用例如:

setorder(DT, x1, x2) 

其中給出:

> DT 
    x1 x2 m1 m2 uN1 uN2 uN3 
1: a 3 30 3 2 1 1 
2: a 5 50 5 2 1 1 
3: b 1 10 1 4 2 2 
4: b 1 10 7 4 2 2 
5: b 4 40 4 4 1 1 
6: b 6 60 6 4 1 1 
7: c 2 20 2 1 1 1 

安排列在不同的順序可以做到像你在你的問題做了:

setcolorder(DT, c('x1','uN1','x2','uN2','m1','uN3','m2'))