19

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$yrledat$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 を自分で再実装してこれを回避することもできますが、グループ化コードが読みにくくなり、車輪の再発明が少し必要になります。cumsumheadtail

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

4

2 に答える 2

13

1つのオプションは、次のように使用するよう{}です:

dat %>%
    group_by(yy = {yy = rle(x); rep(seq_along(yy$lengths), yy$lengths)}) %>%
    summarize(mean(y))
#Source: local data frame [4 x 2]
#
#     yy mean(y)
#  (int)   (dbl)
#1     1     2.0
#2     2     4.5
#3     3     6.0
#4     4     7.0

将来の dplyr のバージョンにも data.table のrleid機能と同等のものがあるとよいでしょう。


または入力を使用するとこの問題が発生するが、data.frameまたはtbl_df入力を使用すると発生しないことに気付きました。tbl_dtdata.table

dat %>% 
    tbl_df %>% 
    group_by(yy = with(rle(x), rep(seq_along(lengths), lengths))) %>%
    summarize(mean(y))
Error: cannot coerce type 'closure' to vector of type 'integer'

dat %>% 
    tbl_dt %>% 
    group_by(yy = with(rle(x), rep(seq_along(lengths), lengths))) %>%
    summarize(mean(y))
Source: local data table [4 x 2]

     yy mean(y)
  (int)   (dbl)
1     1     2.0
2     2     4.5
3     3     6.0
4     4     7.0

これを dplyr の github ページの問題として報告しました。

于 2016-02-10T11:03:57.400 に答える
2

グループ化変数を明示的に作成するgと、多かれ少なかれ機能します。

> dat %>% transform(g=with(rle(dat$x),{ rep(seq_along(lengths), lengths)}))%>%                                   
 group_by(g) %>% summarize(mean(y))
Source: local data frame [4 x 2]

      g mean(y)
  (int)   (dbl)
1     1     2.0
2     2     4.5
3     3     6.0
4     4     7.0

エラーがスローさtransformれるため、ここで使用しました。mutate

于 2016-02-06T22:07:52.220 に答える