学习 plyr ddply - 将函数应用到某个点

learning plyr ddply - applying function up to a point

我正在学习 plyr 包,我正在使用内置 "baseball" 数据集进行练习。这是示例数据(整个数据框比较宽,所以我只发布了从练习的角度来看相关的部分):

data(baseball)
baseball <- baseball[with(baseball, order(id, year)), ]
rownames(baseball) <- NULL
head(baseball[,c("id","year", "ab")])

         id year  ab
1 aaronha01 1954 468
2 aaronha01 1955 602
3 aaronha01 1956 609
4 aaronha01 1957 615
5 aaronha01 1958 601
6 aaronha01 1959 629

我想要做的是向该数据框添加另一列,它将包含最新的平均值 "number of times at bat"(ab 变量),因此对于前 3 行,它看起来像这样:

         id year  ab  atb
1 aaronha01 1954 468  468
2 aaronha01 1955 602  535
3 aaronha01 1956 609  559.6667

现在我知道我应该使用 ddply 和 transform 函数,但我不知道语法应该如何寻找从值到特定索引的平均值:

baseball <- ddply(baseball, ~ id, transform, atb = ???)

非常感谢任何帮助。

这里有一个 data.table 的方法。

# load data.table
library(data.table)
# cast data.frame as data.table
setDT(baseball)

# perform the calculation
baseball[, atb := cumsum(ab) / seq_len(.N), by=id]

这里,atb的计算方法是蝙蝠的累积总和(cumsum(ab))除以该id被观察到该点的年数(seq_len(.N)),计算结果为由 id.

执行

这个returns

head(baseball[,c("id","year", "ab", "atb")])
          id year  ab      atb
1: aaronha01 1954 468 468.0000
2: aaronha01 1955 602 535.0000
3: aaronha01 1956 609 559.6667
4: aaronha01 1957 615 573.5000
5: aaronha01 1958 601 579.0000
6: aaronha01 1959 629 587.3333

在基础 R 中,您可以使用 tapply

完成此操作
baseball$atb2 <- unlist(tapply(baseball$ab, baseball$id,
                               function(i) cumsum(i) / seq_along(i)))

all.equal(baseball$atb, baseball$atb2)
[1] TRUE

这是一个使用 dplyr

的选项
library(dplyr)
baseball %>%
       group_by(id) %>%
       mutate(atb = cummean(ab))

或者我们可以使用 base R

中的 ave
baseball$atb <- with(baseball, ave(ab, id, FUN = function(x) cumsum(x)/seq_along(x)))