web-dev-qa-db-ja.com

Rを使用してデータフレームの複数の列でtapply()を実行するにはどうすればよいですか?

次のようなデータフレームがあります。

_a   b1  b2  b3  b4  b5  b6  b7  b8  b9
D   4   6   9   5   3   9   7   9   8
F   7   3   8   1   3   1   4   4   3
R   2   5   5   1   4   2   3   1   6
D   9   2   1   4   3   3   8   2   5
D   5   4   3   1   6   4   1   8   3
R   3   7   9   1   8   5   3   4   2
D   4   1   8   2   6   3   2   7   5
F   7   1   7   2   7   1   6   2   4
D   6   3   9   3   9   9   7   1   2
_

関数tapply(df[,2], INDEX = df$a, sum)は、df [、2]内のすべてをdf $ aで合計するテーブルを生成するために正常に機能しますが、tapply(df[,2:10], INDEX = df$a, sum)を試して、合計を除いて同様のテーブルを取得しようとすると、各列(2、3、4、.。、10)について、次のエラーメッセージが表示されます。

Tapply(df [、2:10]、INDEX = df $ a、sum)のエラー:引数は同じ長さでなければなりません

さらに、テーブルの行名を_df[,2:10]_の列名にして、行1がb1、行2がb2、行9がb9になるようにします。

20
Jota

これは、tapplyがベクトルに対して機能し、df [、2:10]をベクトルに変換するためです。その横にあるsumは、列ごとの合計ではなく、合計を示します。 aggregate()を使用します。例:

aggregate(df[,2:10],by=list(df$a), sum)

リストを返したい場合は、by()を使用できます。分割されたデータフレームで機能するように、sumではなくcolSumsを指定してください。

by(df[,2:10],df$a,FUN=colSums)
18
Joris Meys

もう1つの可能性は、applytapplyを組み合わせることです。

_apply(df[,-1], 2, function(x) tapply(x, df$a, sum))
_

出力(行列)を生成します

_    b1  ...   b9
D   sD1 ...  sD9
F   sF1 ...  sF9
R   sR1 ...  sR9
_

次に、as.data.frame()を使用して、データフレームを出力として取得できます。

7
Doon_Bogan

この問題にdata.tableを適用する方法は次のとおりです。

library(data.table)
DT <- data.table(df)
DT[, lapply(.SD, sum), by=a]

そしてここにdplyrアプローチがあります

library(dplyr)
df %>% group_by(a) %>% summarise_all(funs(sum))
6
Jota