2017-02-07 2 views
2

data.tableのグループごとのグループごとに、私は行列を作成します。私はこれらのすべての行列を1つの結果として追加したいと思います。以下の例は、よりよく説明しています。data.tableでグルーピングした結果の各行列の合計

set.seed(1) 
library(data.table) 
A <- data.table(A = letters[1:3], B = rnorm(3)) 
fun <- function(dt){ matrix(rnorm(9),nrow = 3, ncol = 3) } 
A[,fun(.SD), by = A] 

この出力は、すべての行列エントリが積み重ねられた列ベクトルです。私は、行列形式を回復するか、別の方法を使用したいと思います。

私は(そう、本当に、私は私の答えを得る方による使用、またはdata.table気にしないだろう)で、私が使用し得るすべての行列を追加したいと思います:

by(A, A$A, fun) 

A$A: a 
      [,1]  [,2]  [,3] 
[1,] -0.6264538 1.5952808 0.4874291 
[2,] 0.1836433 0.3295078 0.7383247 
[3,] -0.8356286 -0.8204684 0.5757814 
-------------------------------------------------------------------------------------- 
A$A: b 
      [,1]  [,2]  [,3] 
[1,] -0.3053884 -0.6212406 -0.04493361 
[2,] 1.5117812 -2.2146999 -0.01619026 
[3,] 0.3898432 1.1249309 0.94383621 
-------------------------------------------------------------------------------------- 
A$A: c 
      [,1]  [,2]  [,3] 
[1,] 0.8212212 0.78213630 0.61982575 
[2,] 0.5939013 0.07456498 -0.05612874 
[3,] 0.9189774 -1.98935170 -0.15579551 
+0

以前誰かが((A、A $ A、楽しい)で、 "+")の削減使うことを提案していたに基づいており、それはかなりうまくいきました。残念ながら、その人は答えを削除しました – dleal

+1

@フランク - あなたがコメントしたものと同じようなものを入力していました。答えとして追加する必要があります。 – thelatemail

+1

@Frank - ok - 私はあなたにバーチャルビールを借りています。 – thelatemail

答えて

2

結果byは行列の単なるリストです。だから、単純に(How to sum a numeric list elements in Rを参照)、リストのすべての要素を追加することができます。

> set.seed(1) 
> A <- data.table(A = letters[1:3], B = rnorm(3)) 
> fun <- function(dt){ matrix(rnorm(9),nrow = 3, ncol = 3) } 
> l <- by(A, A$A, fun) 
> Reduce("+",l) 
      [,1]  [,2]  [,3] 
[1,] 1.756177 1.0623212 -0.9549196 
[2,] -1.810627 0.6660057 1.6275324 
[3,] -1.684889 1.3638221 1.7267622 
> l[[1]] + l[[2]] + l[[3]] 
      [,1]  [,2]  [,3] 
[1,] 1.756177 1.0623212 -0.9549196 
[2,] -1.810627 0.6660057 1.6275324 
[3,] -1.684889 1.3638221 1.7267622 
+0

私はこの答えが好きです。オブジェクトの構造を理解するのに役立ち、追加のライブラリは必要ありませんでした。 – dleal

2

したい場合は、jにネストlistまたは.()の別のレベルを追加することにより、data.table内にとどまることができます。

A[,.(mats=.(fun(.SD))), by = A][, Reduce(`+`, mats)] 
#   [,1]  [,2]  [,3] 
#[1,] 1.756177 1.0623212 -0.9549196 
#[2,] -1.810627 0.6660057 1.6275324 
#[3,] -1.684889 1.3638221 1.7267622 
1

ここにはtidyverseのアプローチがあります

library(tidyverse) 
A %>% 
    split(.$A) %>% 
    map(fun) %>% 
    reduce(`+`) 
#  [,1]  [,2]  [,3] 
#[1,] -2.9614395 3.9622030 2.0717522 
#[2,] 2.9163822 0.7773892 0.3030291 
#[3,] 0.4163046 -1.1495702 -1.4320626 

注:出力の違いv aluesはseed選択すなわち

set.seed(24) 
Reduce(`+`, by(A, A$A, fun)) 
#   [,1]  [,2]  [,3] 
#[1,] 0.06642572 -1.9509985 -0.6730669 
#[2,] -0.26398712 -2.2912755 -0.8955920 
#[3,] 0.94358370 0.3295733 0.6023412 

set.seed(24) 
A %>% 
    split(.$A) %>% 
    map(fun) %>% 
    reduce(`+`) 
#   [,1]  [,2]  [,3] 
#[1,] 0.06642572 -1.9509985 -0.6730669 
#[2,] -0.26398712 -2.2912755 -0.8955920 
#[3,] 0.94358370 0.3295733 0.6023412 
関連する問題