11

これはおそらくばかげた質問ですが、私はデータフレームに関するCrawleyの章を読み、インターネットを精査しましたが、まだ何も機能させることができていません。

これが私のようなサンプルデータセットです:

> data<-data.frame(site=c("A","A","A","A","B","B"), plant=c("buttercup","buttercup",
"buttercup","rose","buttercup","rose"), treatment=c(1,1,2,1,1,1), 
plant_numb=c(1,1,2,1,1,2), fruits=c(1,2,1,4,3,2),seeds=c(45,67,32,43,13,25))
> data
  site     plant treatment plant_numb fruits seeds
1    A buttercup         1          1      1    45
2    A buttercup         1          1      2    67
3    A buttercup         2          2      1    32
4    A      rose         1          1      4    43
5    B buttercup         1          1      3    13
6    B      rose         1          2      2    25  

私がやりたいのは、固有のサイトと植物と処理とplant_numbの組み合わせが存在する場合は常に、「シード」と「フルーツ」が合計されるシナリオを作成することです。理想的には、これにより行が削減されますが、元の列は保持されます(つまり、上記の例は次のようになります:)

  site     plant treatment plant_numb fruits seeds
1    A buttercup         1          1      3   112
2    A buttercup         2          2      1    32
3    A      rose         1          1      4    43
4    B buttercup         1          1      3    13
5    B      rose         1          2      2    25

この例は非常に基本的であり(私のデータセットは約5000行です)、ここでは合計する必要のある2行のみが表示されますが、合計する必要のある行数は1から約45の範囲です。

私はこれまでrowsum()とtapply()を試しましたが、かなり悲惨な結果になりました(エラーは、これらの関数が要因にとって意味がないことを示しています)。正しい方向に向けることができれば、非常にありがたいです。 !!

本当にありがとう!

4

3 に答える 3

11

うまくいけば、次のコードはかなり自明です。これは基本関数「aggregate」を使用します。基本的に、これは、site、plant、treatment、およびplant_numの一意の組み合わせごとに、果物の合計と種子の合計を確認することを意味します。

# Load your data
data <- data.frame(site=c("A","A","A","A","B","B"), plant=c("buttercup","buttercup",
"buttercup","rose","buttercup","rose"), treatment=c(1,1,2,1,1,1), 
plant_numb=c(1,1,2,1,1,2), fruits=c(1,2,1,4,3,2),seeds=c(45,67,32,43,13,25)) 

# Summarize your data
aggregate(cbind(fruits, seeds) ~ 
      site + plant + treatment + plant_numb, 
      sum, 
      data = data)
#  site     plant treatment plant_numb fruits seeds
#1    A buttercup         1          1      3   112
#2    B buttercup         1          1      3    13
#3    A      rose         1          1      4    43
#4    B      rose         1          2      2    25
#5    A buttercup         2          2      1    32

行の順序は変わります(そして、サイト、プラントなどでソートされます)が、それがそれほど問題にならないことを願っています。

これを行う別の方法は、plyrパッケージのddplyを使用することです。

library(plyr)
ddply(data, .(site, plant, treatment, plant_numb), 
      summarize, 
      fruits = sum(fruits), 
      seeds = sum(seeds))
#  site     plant treatment plant_numb fruits seeds
#1    A buttercup         1          1      3   112
#2    A buttercup         2          2      1    32
#3    A      rose         1          1      4    43
#4    B buttercup         1          1      3    13
#5    B      rose         1          2      2    25
于 2012-05-03T03:45:20.920 に答える
4

そして完全を期すためにdata.table、@Chaseが提案した解決策を次に示します。より大きなデータセットの場合、これがおそらく最速の方法です。

library(data.table)
data.dt <- data.table(data)
setkey(data.dt, site)
data.dt[, lapply(.SD, sum), by = list(site, plant, treatment, plant_numb)]

     site     plant treatment plant_numb fruits seeds
[1,]    A buttercup         1          1      3   112
[2,]    A buttercup         2          2      1    32
[3,]    A      rose         1          1      4    43
[4,]    B buttercup         1          1      3    13
[5,]    B      rose         1          2      2    25

このlapply(.SD, sum)部分は、グループ化セットの一部ではないすべての列(つまり、by関数にない列)を合計します。

于 2012-05-03T04:33:39.350 に答える
0

ずっと後にこの答えを更新するだけで、dplyr/tidyverseソリューションは次のようになります

library(tidyverse)

data %>% 
  group_by(site, plant, treatment, plant_numb) %>% 
  summarise(fruits=sum(fruits), seeds=sum(seeds))
于 2018-12-11T23:24:45.530 に答える