Rでは、変数の実行に基づいてデータをグループ化した後、データを要約したいと考えています(別名、データの各グループは、連続する値が同じx
であるデータのサブセットに対応しています)。x
たとえば、y
各実行内の平均値を計算する次のデータ フレームを考えてみx
ます。
(dat <- data.frame(x=c(1, 1, 1, 2, 2, 1, 2), y=1:7))
# x y
# 1 1 1
# 2 1 2
# 3 1 3
# 4 2 4
# 5 2 5
# 6 1 6
# 7 2 7
この例では、x
変数には長さ 3、2、1、最後に 1 のランがあり、これら 4 つのランで値 1、2、1、および 2 を取ります。これらのグループの対応する平均はy
、2、4.5、6、および 7 です。
を使用してベース R でグループ化された操作を実行し、データとしてtapply
渡し、 を使用して から実行番号を計算し、目的の集計関数を渡すのは簡単です。dat$y
rle
dat$x
tapply(dat$y, with(rle(dat$x), rep(seq_along(lengths), lengths)), mean)
# 1 2 3 4
# 2.0 4.5 6.0 7.0
このロジックを dplyr にかなり直接引き継ぐことができると考えましたが、これまでの試みはすべてエラーに終わりました。
library(dplyr)
# First attempt
dat %>%
group_by(with(rle(x), rep(seq_along(lengths), lengths))) %>%
summarize(mean(y))
# Error: cannot coerce type 'closure' to vector of type 'integer'
# Attempt 2 -- maybe "with" is the problem?
dat %>%
group_by(rep(seq_along(rle(x)$lengths), rle(x)$lengths)) %>%
summarize(mean(y))
# Error: invalid subscript type 'closure'
完全を期すために、、 、rle
を使用して実行 ID を自分で再実装してこれを回避することもできますが、グループ化コードが読みにくくなり、車輪の再発明が少し必要になります。cumsum
head
tail
dat %>%
group_by(run=cumsum(c(1, head(x, -1) != tail(x, -1)))) %>%
summarize(mean(y))
# run mean(y)
# (dbl) (dbl)
# 1 1 2.0
# 2 2 4.5
# 3 3 6.0
# 4 4 7.0
rle
でベースのグループ化コードが失敗する原因は何ですか? また、実行 ID でグループ化するときdplyr
に引き続き使用できるようにする解決策はありますか?rle