Применение скользящего среднего по группе в R
Я новичок в R, и у меня много проблем с чем-то, что, вероятно, очень просто. У меня есть большой набор данных, разбитый на группы по коду страны, и я хочу взять 3-месячный скользящий средний индекс цен по странам, а затем поместить его в новый столбец, соответствующий соответствующему месяцу. Я пытаюсь использовать rollmean как это без успеха (коды и сообщения об ошибках ниже):
> leader$last3<-tapply(leader, leader$ccode,
function(x) rollmean(leader$GI_delta, 3, na.pad=T))
Error in tapply(leader, leader$ccode, function(x) rollmean(leader$GI_delta, :
arguments must have same length
> leader$last3<-ddply(leader, .(ccode),
rollmean(GI_delta, 3, na.pad=T))
Error in llply(.data = .data, .fun = .fun, ..., .progress = .progress, :
.fun is not a function.
Любая помощь будет очень признательна!
Ответы
Ответ 1
Если вы хотите создать новый столбец, попробуйте использовать ave
. Он напоминает tapply
, но возвращает вектор той же длины, что и его первый аргумент. Мой опыт в том, что он намного быстрее, чем ddply
:
require(zoo)
leader$last3<-ave(leader$GI_delta, leader$ccode,
FUN= function(x) rollmean(x, k=3, na.pad=T) )
Ответ 2
В вашей первой попытке ваша функция не использует свой аргумент x
и всегда возвращает одно и то же (вектор с неправильным размером).
Кроме того, первым аргументом должен быть вектор.
Наконец, tapply
возвращает список векторов:
вы не можете поместить результат непосредственно в файл data.frame.
library(zoo)
n <- 10
leader <- data.frame(
ccode = rep(LETTERS[1:3],each=n),
GI_delta = rnorm(3*n)
)
tapply(
leader$GI_delta,
leader$ccode,
function(x) rollmean(x, 3, na.pad=TRUE)
)
В вашем втором примере третий аргумент plyr
должна быть функцией, а не выражением.
Если вы хотите использовать выражение, вы можете использовать summarize
или transform
как функция (summarize
возвращает 1-строчный data.frame
для каждого значения ccode
, тогда как transform
сохраняет количество строк без изменений),
и поместите выражения в качестве дополнительных аргументов.
library(plyr)
ddply(
leader, "ccode",
transform,
last3 = rollmean( GI_delta, 3, align="right", na.pad=TRUE )
)