2012-03-10 20 views
10

Soy un novato en R y estoy teniendo muchos problemas para hacer algo que probablemente sea muy simple. Tengo un gran conjunto de datos divididos en grupos por código de país, y quiero tomar un promedio móvil de 3 meses de un índice de precios, por país, y luego ponerlo en una nueva columna que coincida hasta el mes correspondiente. He estado tratando de utilizar rollmean como esto sin éxito (código de error y mensajes de abajo):aplicando la media móvil por grupo en R

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

Cualquier ayuda sería muy apreciada!

Respuesta

5

En su primer intento, su función no usa su argumento x, y siempre devuelve lo mismo (un vector con el tamaño incorrecto). Además, el primer argumento, debería ser un vector. Por último, tapply devuelve una lista de vectores: no se puede poner el resultado directamente en un 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) 
) 

En el segundo ejemplo, el tercer argumento de plyr debería ser una función, no una expresión. Si desea utilizar una expresión, puede utilizar summarize o transform como una función (summarize devuelve una fila hoja.de.datos 1- para cada valor de ccode, mientras transform mantiene el número de filas sin cambios), y poner las expresiones como argumentos adicionales.

library(plyr) 
ddply(
    leader, "ccode", 
    transform, 
    last3 = rollmean(GI_delta, 3, align="right", na.pad=TRUE) 
) 
+0

Gracias por su ayuda Vincent! –

13

Si desea hacer una nueva columna, a continuación, tratar de usar ave. Se asemeja a tapply pero devuelve un vector de la misma longitud que su primer argumento. Mi experiencia es que es mucho más rápido que ddply:

require(zoo) 
leader$last3<-ave(leader$GI_delta, leader$ccode, 
         FUN= function(x) rollmean(x, k=3, na.pad=T)) 
+0

Gracias, esto funciona genial! –

Cuestiones relacionadas