6

data.table を使用して、選択した列全体で統計を「一掃」する最も速い方法はどれですか?

(かなり大きなバージョンの) DT から始める

p <- 3
DT <- data.table(id=c("A","B","C"),x1=c(10,20,30),x2=c(20,30,10))
DT.totals <- DT[, list(id,total = x1+x2) ]

キーをスキップするために、ターゲット列 (2:p) にインデックスを付けて、次の data.table の結果を取得したいと思います。

    id  x1  x2
[1,]    A   0.33    0.67
[2,]    B   0.40    0.60
[3,]    C   0.75    0.25
4

1 に答える 1

4

次のようなもの(比較的新しいset()関数を使用)が最も速いと思います。

DT <- data.table(id = c("A","B","C"), x1 = c(10,20,30), x2 = c(20,30,10))
total <- DT[ , x1 + x2]

rr <- seq_len(nrow(DT))
for(j in 2:3) set(DT, rr, j, DT[[j]]/total) 
DT
#      id        x1        x2
# [1,]  A 0.3333333 0.6666667
# [2,]  B 0.4000000 0.6000000
# [3,]  C 0.7500000 0.2500000

FWIW、への呼び出しset()は次の形式を取ります。

# set(x, i, j, value), where: 
#     x is a data.table 
#     i contains row indices
#     j contains column indices 
#     value is the value to be assigned into the specified cells

他のソリューションと比較した場合のこれの相対速度についての私の疑惑は、バージョン1.8.0での変更に関するセクションのdata.tableのNEWSファイルからのこの一節に基づいています。

o   New function set(DT,i,j,value) allows fast assignment to elements
    of DT. Similar to := but avoids the overhead of [.data.table, so is
    much faster inside a loop. Less flexible than :=, but as flexible
    as matrix subassignment. Similar in spirit to setnames(), setcolorder(),
    setkey() and setattr(); i.e., assigns by reference with no copy at all.

        M = matrix(1,nrow=100000,ncol=100)
        DF = as.data.frame(M)
        DT = as.data.table(M)
        system.time(for (i in 1:1000) DF[i,1L] <- i)   # 591.000s
        system.time(for (i in 1:1000) DT[i,V1:=i])     #   1.158s
        system.time(for (i in 1:1000) M[i,1L] <- i)    #   0.016s
        system.time(for (i in 1:1000) set(DT,i,1L,i))  #   0.027s
于 2012-04-11T17:54:50.963 に答える