2017-01-19 9 views
0

Я изучаю пакет plyr, я использую встроенный набор данных «бейсбол» для своих упражнений. Вот пример данных (весь кадр данных достаточно широк, так что я только разместил часть, которая имеет отношение с точки тренировки зрения):learning plyr ddply - применение функции до точки

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 

То, что я хочу сделать, это добавить еще один столбец что кадр данных, который будет содержать среднее «количество раз в летучей мыши» (переменные абы) до настоящего времени, так что в течение 3 первых строк она будет выглядеть следующим образом:

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

Теперь я знаю, что я должен использовать ddply и преобразование но я не знаю, как синтаксис должен искать получение значения от значений до определенного индекса:

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

Поблагодарили бы за любую помощь.

+1

Вы можете считать правопреемником 'plyr'package:' dplyr'. Там вы найдете функцию 'cummean'. Или просто 'base':' cumsum (df $ ab)/seq_along (df $ ab) '. – Henrik

+0

Спасибо, второй синтаксис был именно тем, что я искал! – 3michalzak

ответ

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)), и расчет выполняется по идентификатору.

это возвращает

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 
+0

Большое вам спасибо, что сделал трюк! – 3michalzak

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)))