8

Rに大きなデータテーブルがあります:

library(data.table)
set.seed(1234)
n <- 1e+07*2
DT <- data.table(
  ID=sample(1:200000, n, replace=TRUE), 
  Month=sample(1:12, n, replace=TRUE),
  Category=sample(1:1000, n, replace=TRUE),
  Qty=runif(n)*500,
  key=c('ID', 'Month')
)
dim(DT)

カテゴリが列になるように、この data.table をピボットしたいと思います。残念ながら、カテゴリの数はグループ内で一定ではないため、この回答は使用できません。

これを行う方法はありますか?

/編集:joranのコメントとflodelの回答に基づいて、実際に次のように再形成していますdata.table

agg <- DT[, list(Qty = sum(Qty)), by = c("ID", "Month", "Category")]

この再形成はさまざまな方法で実現できます (これまでのところ、いくつかの良い答えが得られています) が、私が本当に探しているのはdata.table、数百万の行と数百から数千のカテゴリにうまくスケーリングできるものです。

4

4 に答える 4

3

data.table特定のワイド リシェイプ方法はありません。

これは機能するアプローチですが、かなり複雑です。

これをより簡単にするための機能リクエスト#2619 Scoping for LHS があります。:=

ここに簡単な例があります

# a data.table
DD <- data.table(a= letters[4:6], b= rep(letters[1:2],c(4,2)), cc = as.double(1:6))
# with not all categories represented
DDD <- DD[1:5]
# trying to make `a` columns containing `cc`. retaining `b` as a column
# the unique values of `a` (you may want to sort this...)
nn <- unique(DDD[,a])
# create the correct wide data.table
# with NA of the correct class in each created column
rows <- max(DDD[, .N,  by = list(a,b)][,N])
DDw <- DDD[, setattr(replicate(length(nn), {
                     # safe version of correct NA  
                     z <- cc[1]
                      is.na(z) <-1
                     # using rows value calculated previously
                     # to ensure correct size
                       rep(z,rows)}, 
                    simplify = FALSE), 'names', nn),
           keyby = list(b)]
# set key for binary search
setkey(DDD, b, a)
# The possible values of the b column
ub <- unique(DDw[,b])
# nested loop doing things by reference, so should be 
# quick (the feature request would make this possible to 
# speed up using binary search joins.
for(ii in ub){
  for(jj in nn){
    DDw[list(ii), {jj} := DDD[list(ii,jj)][['cc']]]
  }
}

DDw
#    b  d e  f
# 1: a  1 2  3
# 2: a  4 2  3
# 3: b NA 5 NA
# 4: b NA 5 NA
于 2013-04-04T23:19:40.280 に答える