3

私はこれらの線に沿ってデータセットを持っています:

df<-data.frame(sp=c(100, 100, 100, 101, 101, 101, 102, 102, 102),
type=c("C","C","C","H","H","H","C","C","C"),
country=c("A", "A", "A", "B", "B", "B", "C", "C", "C"),
vals=c(1,2,3,4,5,6,7,8,9)
)

df $ valsを集計し、他の変数も取得したい

現時点では、次のように実行しています。

multi.func<- function(x){
c(
n = length(x),
min = min(x, na.rm=TRUE),
max = max(x, na.rm=TRUE),
mean = mean(x, na.rm=TRUE)
)}

aggVals<-as.data.frame(do.call(rbind, by(df$vals, df$sp, FUN=multi.func, simplify=TRUE)))
aggVals$sp<-row.names(aggVals)

aggDescrip<-aggregate(cbind(as.character(type), as.character(country)) ~ sp, data=df, FUN=unique)

result<-merge(aggDescrip,aggVals)

これは十分に機能しますが、もっと簡単な方法があるかどうか疑問に思いました。

ありがとう

4

2 に答える 2

3

data.tableおそらく、パッケージを調べる必要があります。

library(data.table)
DT <- data.table(df, key="sp")
DT[, list(type = unique(as.character(type)), 
          country = unique(as.character(country)), 
          n = .N, min = min(vals), max = max(vals), 
          mean = mean(vals)), by=key(DT)]
#     sp type country n min max mean
# 1: 100    C       A 3   1   3    2
# 2: 101    H       B 3   4   6    5
# 3: 102    C       C 3   7   9    8

ベースRを使い続けたい場合は、次のアプローチが役立つ可能性があります(aggregateおそらくより一般的ですが)。

unique(within(df, {
    mean <- ave(vals, sp, FUN=mean)
    max <- ave(vals, sp, FUN=max)
    min <- ave(vals, sp, FUN=min)
    n <- ave(vals, sp, FUN=length)
    rm(vals)
}))
#    sp type country n min max mean
# 1 100    C       A 3   1   3    2
# 4 101    H       B 3   4   6    5
# 7 102    C       C 3   7   9    8

更新:最初の試みのバリエーション

data.table結果のコードはわかりやすく、集計プロセスが速いため、可能であれば固執することをお勧めします。

ただし、少し変更を加えるだけで、(さらに別の)ベースRアプローチを使用できます。これはやや直接的です。

c()まず、を使用する代わりにを使用するように関数を変更しますdata.frame。また、どの列を集約する必要があるかを指定する引数を追加します。

multi.func <- function(x, value_column) {
    data.frame(
        n = length(x[[value_column]]),
        min = min(x[[value_column]], na.rm=TRUE),
        max = max(x[[value_column]], na.rm=TRUE),
        mean = mean(x[[value_column]], na.rm=TRUE))
}

次に、lapplyデータセットで、splitグループ化変数を使用しmergeて、元のデータセットの出力を使用し、値を返しuniqueます。

unique(merge(df[-4], 
             do.call(rbind, lapply(split(df, df$sp), 
                                   multi.func, value_column = "vals")),
             by.x = "sp", by.y = "row.names"))
于 2012-12-17T15:51:10.623 に答える
2

使用するだけaggregate

result <- aggregate(vals ~ type + sp + country, df, 
    function(x) c(length(x), min(x), max(x), mean(x))
)

result
  type  sp country vals.1 vals.2 vals.3 vals.4
1    C 100       A      3      1      3      2
2    H 101       B      3      4      6      5
3    C 102       C      3      7      9      8

colnames(result)
[1] "type"    "sp"      "country" "vals"  

上記は奇妙な「複数値」列を作成しているようです。しかしsummaryBydoByパッケージからは似てaggregateいますが、複数の列を持つ出力が可能になります。

library(doBy)
result <- summaryBy(vals ~ type + sp + country, df, 
    FUN=function(x) c(n=length(x), min=min(x), max=max(x), mean=mean(x))
)

result
  type  sp country vals.n vals.min vals.max vals.mean
1    C 100       A      3        1        3         2
2    C 102       C      3        7        9         8
3    H 101       B      3        4        6         5

colnames(result)
[1] "type"      "sp"        "country"   "vals.n"    "vals.min"  "vals.max" 
[7] "vals.mean"
于 2012-12-17T15:10:18.227 に答える