学习plyr ddply - 将功能应用到一个点

时间:2017-01-19 21:02:16

标签: r plyr

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

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

我想要做的是在该数据框中添加另一列,其中包含平均&#34;次数#bat;#34; (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 = ???)

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

以下是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))除以在该点(seq_len(.N))之前观察到id的年数,并且计算由标识。

返回

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

答案 1 :(得分:0)

以下是使用dplyr

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

或者我们可以使用ave

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