22

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

experiment iter  results
    A       1     30.0
    A       2     23.0
    A       3     33.3
    B       1     313.0
    B       2     323.0
    B       3     350.0
 ....

条件付きの関数を適用して結果を集計する方法はありますか。上記の例では、その条件は特定の実験のすべての反復です。

A   sum of results (30 + 23, + 33.3)
B   sum of results (313 + 323 + 350)

「適用」機能を考えていますが、機能させる方法が見つかりません。

4

1 に答える 1

52

これを行うには多くの代替手段があります。とは異なる別の関数に関心がある場合は、sum引数FUN=any.functionを変更するだけでよいことmeanに注意してください。いくつかの代替案を見てみましょう。var lengthFUNFUN=meanFUN=var

aggregateベースで機能します。

> aggregate(results ~ experiment, FUN=sum, data=DF)
  experiment results
1          A    86.3
2          B   986.0

それとも多分tapply

> with(DF, tapply(results, experiment, FUN=sum))
    A     B 
 86.3 986.0 

こちらもddplyプライアパッケージから

> # library(plyr)
> ddply(DF[, -2], .(experiment), numcolwise(sum))
  experiment results
1          A    86.3
2          B   986.0

> ## Alternative syntax
> ddply(DF, .(experiment), summarize, sumResults = sum(results))
  experiment sumResults
1          A       86.3
2          B      986.0

dplyrパッケージも

> require(dplyr)
> DF %>% group_by(experiment) %>% summarise(sumResults = sum(results))
Source: local data frame [2 x 2]

  experiment  sumResults
1          A        86.3
2          B       986.0

とを使用するsapplysplit、 と同等tapplyです。

> with(DF, sapply(split(results, experiment), sum))
    A     B 
 86.3 986.0 

タイミングが気になるなら、data.tableあなたの友達は:

> # library(data.table)
> DT <- data.table(DF)
> DT[, sum(results), by=experiment]
   experiment    V1
1:          A  86.3
2:          B 986.0

あまり人気はありませんが、doBy パッケージは便利です (aggregate構文的にも , と同等です!)

> # library(doBy)
> summaryBy(results~experiment, FUN=sum, data=DF)
  experiment results.sum
1          A        86.3
2          B       986.0

こんな時にもby役立ちます

> (Aggregate.sums <- with(DF, by(results, experiment, sum)))
experiment: A
[1] 86.3
------------------------------------------------------------------------- 
experiment: B
[1] 986

結果を行列にしたい場合は、またはのいずれcbindかを使用しますrbind

> cbind(results=Aggregate.sums)
  results
A    86.3
B   986.0

sqldfsqldfパッケージからも良いオプションかもしれません

> library(sqldf)
> sqldf("select experiment, sum(results) `sum.results`
      from DF group by experiment")
  experiment sum.results
1          A        86.3
2          B       986.0

xtabsも動作します ( の場合のみFUN=sum)

> xtabs(results ~ experiment, data=DF)
experiment
    A     B 
 86.3 986.0
于 2013-05-20T20:11:18.750 に答える