これは例で最もよく説明されています
str(mtcars)
mtcars$gear <- factor(mtcars$gear, labels=c("three","four","five"))
mtcars$cyl <- factor(mtcars$cyl, labels=c("four","six","eight"))
mtcars$am <- factor(mtcars$am, labels=c("manual","auto")
str(mtcars)
tapply(mtcars$mpg, mtcars$gear, sum)
これにより、ギアごとの合計mpgが得られます。しかし、上部にギアがあり、側面にシリンダーがあり、2変量の合計が9つのセルになっている3x3テーブルが必要だったとしたら、どうすれば「スマート」にできますか。
行くことができました。
tapply(mtcars$mpg[mtcars$cyl=="four"], mtcars$gear[mtcars$cyl=="four"], sum)
tapply(mtcars$mpg[mtcars$cyl=="six"], mtcars$gear[mtcars$cyl=="six"], sum)
tapply(mtcars$mpg[mtcars$cyl=="eight"], mtcars$gear[mtcars$cyl=="eight"], sum)
これは扱いにくいようです。
それでは、どのようにして3番目の変数をミックスに組み込むのでしょうか。
これは、私が考えているスペースに多少あります。 ddplyを使用した要約統計
updateこれは私をそこに連れて行きますが、きれいではありません。
aggregate(mpg ~ am+cyl+gear, mtcars,sum)
乾杯
まだtapply()
を使っていますか?それはあなたが知っているよりも用途が広いです!
with(mtcars, tapply(mpg, list(cyl, gear), sum))
# three four five
# four 21.5 215.4 56.4
# six 39.5 79.0 19.7
# eight 180.6 NA 30.8
または、印刷出力をもう少しわかりやすくしたい場合は、次のようにします。
with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), sum))
3つ以上の相互分類変数を使用する場合も、考え方はまったく同じです。結果は3次元以上の配列で返されます。
A <- with(mtcars, tapply(mpg, list(cyl, gear, carb), sum))
dim(A)
# [1] 3 3 6
lapply(1:6, function(i) A[,,i]) # To convert results to a list of matrices
# But eventually, the curse of dimensionality will begin to kick in...
table(is.na(A))
# FALSE TRUE
# 12 42
この質問の回答は素晴らしいオプションだと思いますが、dplyr
パッケージに基づいて追加のオプションを共有したいと思いました(これは、私がdplyr
はデータ操作に使用するため、tapply
やaggregate
などの特殊なベースR関数を生徒に紹介しないようにしました。
group_by
関数を使用して、必要な数の変数をグループ化し、これらのグループからの情報をsummarize
で要約できます。このコードは、Rの初心者にとって、数式ベースのaggregate
のインターフェイスよりも読みやすく、同じ結果が得られると思います。
library(dplyr)
mtcars %>%
group_by(am, cyl, gear) %>%
summarize(mpg=sum(mpg))
# am cyl gear mpg
# (dbl) (dbl) (dbl) (dbl)
# 1 0 4 3 21.5
# 2 0 4 4 47.2
# 3 0 6 3 39.5
# 4 0 6 4 37.0
# 5 0 8 3 180.6
# 6 1 4 4 168.2
# 7 1 4 5 56.4
# 8 1 6 4 42.0
# 9 1 6 5 19.7
# 10 1 8 5 30.8
2つの変数を使用すると、spread
パッケージからtidyr
関数への呼び出しを追加することにより、行の1つの変数と列のもう1つの変数で要約できます。
library(dplyr)
library(tidyr)
mtcars %>%
group_by(cyl, gear) %>%
summarize(mpg=sum(mpg)) %>%
spread(gear, mpg)
# cyl 3 4 5
# (dbl) (dbl) (dbl) (dbl)
# 1 4 21.5 215.4 56.4
# 2 6 39.5 79.0 19.7
# 3 8 180.6 NA 30.8
私はこれに対するジョシュの答えが好きですが、reshape2
は、これらのタイプの問題に適切なフレームワークを提供することもできます。
library(reshape2)
#use subset to only grab the variables of interest...
mtcars.m <- melt(subset(mtcars, select = c("mpg", "gear", "cyl")), measure.vars="mpg")
#cast into appropriate format
dcast(mtcars.m, cyl ~ gear, fun.aggregate=sum, value.var="value")
cyl three four five
1 four 21.5 215.4 56.4
2 six 39.5 79.0 19.7
3 eight 180.6 0.0 30.8
答えには、tapplyおよびaggregate関数を使用した同じ出力が含まれています。
Josh O'Brienの回答にいくつかの情報を追加したいと思います。ユーザーは、出力に応じて集約関数またはタッププライのいずれかを使用できます。 Tapplyで複数の因子変数を使用するには、Joshが示した方法を使用できます。
データセットを読み込んでいます
data("mtcars")
Tapplyの使用
with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear), sum))
上記のコードの出力は
Gear#
Cylinder# 3 4 5
4 21.5 215.4 56.4
6 39.5 79.0 19.7
8 180.6 NA 30.8
集計関数の使用
with(mtcars, aggregate(mpg, list(Cylinder = cyl, Gear = gear), sum))
集計関数の出力
Cylinder Gear x
1 4 3 21.5
2 6 3 39.5
3 8 3 180.6
4 4 4 215.4
5 6 4 79.0
6 4 5 56.4
7 6 5 19.7
8 8 5 30.8
ここで、ユーザーが集約関数と同じ出力を望んでいるが、tapplyを使用している場合。
as.data.frame(as.table(with(mtcars, tapply(mpg, list("Cylinder#"=cyl, "Gear#"=gear),
sum))))
Tapply関数の出力
Cylinder. Gear. Freq
1 4 3 21.5
2 6 3 39.5
3 8 3 180.6
4 4 4 215.4
5 6 4 79.0
6 8 4 NA
7 4 5 56.4
8 6 5 19.7
9 8 5 30.8
NAは、ビジネス要件に従って保持または削除できます。