変換

2016-08-29 3 views
0

私は下記のおもちゃの例のように、Rのdata.tableからネストされたリストを作成したいと思わ:変換

library(data.table) 

generate_dt <- function(num_unique_id=100, rows_per_id=2) { 
    num_rows <- num_unique_id * rows_per_id 
    my_dt <- data.table(my_id=rep(seq(1, num_unique_id), rows_per_id), 
         y1=rnorm(num_rows), y2=rnorm(num_rows), y3=rnorm(num_rows), 
         z=runif(num_rows)) 
    setkey(my_dt, my_id) 
    return(my_dt) 
} 

## Suppose I want to go from my_dt to a nested list 
list_from_dt <- function(my_dt) { 
    num_unique_id <- length(unique(my_dt$my_id)) 
    my_list <- lapply(seq_len(num_unique_id), function(id) { 
     my_dt_subset <- my_dt[J(id)] 
     return(list(y=as.matrix(my_dt_subset[, c("y1", "y2", "y3"), with=FALSE]), 
        max_z=max(my_dt_subset$z))) 

    }) 
    stopifnot(is.matrix(my_list[[1]]$y)) 
    return(my_list) 
} 

my_dt <- generate_dt() 
my_list <- list_from_dt(my_dt) # Suppose I have some code that expects a nested list like this 

system.time(replicate(100, unused <- generate_dt())) # Fast, 0.062 elapsed 
system.time(replicate(100, unused <- list_from_dt(my_dt))) # Roughly 200 times slower (12.586 elapsed) 

なぜ、ネストされたリストを作成していますデータテーブルの作成に比べて遅いですか?私のlist_from_dt機能をスピードアップする方法はありますか?私はmy_dtへのルックアップは比較的速いと仮定しています。ボトルネックは、ネストされたリスト内のマトリックスのための小さな断片化されたメモリの多くを割り当てることから来ていますか?ここで

+2

つまり、objを分割して要約統計量を計算するのが遅いのは当然のことです。また、単一のオブジェクトを作成することも高速です。 'lapply(split(...))'に興味があるかもしれません。 'split.data.table'関数は効率的で、パッケージのdevelバージョン(1.9.7)で利用できます。 – Frank

+0

@Frankそのポインタをありがとう、私はしようとdata.table 1.9.7作業(私は1.9.6持っている)を取得します。私はlist_from_dtが遅いのは驚きではないが、私はどれくらい遅いのかに驚いている。データをコピーするだけではあまり計算が行われません。 – Adrian

答えて

2

は、私がsplitgmaxで見たものです。

f = function(){ 
    s = lapply(split(my_dt[, !"z", with=FALSE], by="my_id", keep.by=FALSE), as.matrix) 
    mz = my_dt[, max(z), by=my_id] 
    Map(list, ys = s, mz = mz$V1) 
} 

system.time(replicate(100, generate_dt()))   # 0.1 
system.time(replicate(100, list_from_dt(my_dt))) # 20.1 
system.time(replicate(100, f()))     # 2.1 

それは次のようになります。

> head(res, 2) 
$`1` 
$`1`$ys 
       y1   y2   y3 
[1,] -0.04493979 -1.01340856 0.08481358 
[2,] -0.75860610 0.04113645 -0.36270441 

$`1`$mz 
[1] 0.9362695 


$`2` 
$`2`$ys 
      y1   y2  y3 
[1,] 0.7718361 -0.8005803 1.2195464 
[2,] 0.1658420 -1.2846028 0.4607024 

$`2`$mz 
[1] 0.8551927 

番号、`1``2`は現在、リスト要素の名前として、my_id値であり、 。