2012-05-09 1 views
1

Мне нужно рассчитать и добавить к кадру данных несколько новых столбцов на основе значений в каждом столбце в поднаборе столбцов в кадре данных. В этих столбцах хранятся данные временных рядов (имеется общий столбец даты). Например, мне нужно рассчитать изменение за тот же месяц в предыдущем году для дюжины столбцов. Я мог бы указать их и рассчитать их отдельно, но это становится обременительным с большим количеством столбцов для преобразования, поэтому я пытаюсь автоматизировать процесс с циклом for.R: использование ddply в цикле над столбцами фрейма данных

Я делал все ОК, пока не попытался использовать ddply, чтобы создать столбец для текущей общей суммы за год. Что происходит, так это то, что ddply добавляет новые строки во время каждой итерации через цикл и включает в себя эти новые строки в вычислении cumsum. У меня есть два вопроса.

В. Как я могу получить ddply для вычисления правильной cumsum? В. Как я могу указать имя столбца во время вызова ddply, вместо использования фиктивного значения и переименования потом?

[Edit: я говорил слишком рано, обновленный код ниже не работает на данный момент, просто FYI]

require(lubridate) 
require(plyr) 
require(xts) 

set.seed(12345) 
# create dummy time series data 
monthsback <- 24 
startdate <- as.Date(paste(year(now()),month(now()),"1",sep = "-")) - months(monthsback) 
mydf <- data.frame(mydate = seq(as.Date(startdate), by = "month", length.out = monthsback), 
        myvalue1 = runif(monthsback, min = 600, max = 800), 
        myvalue2 = runif(monthsback, min = 200, max = 300)) 

mydf$year <- as.numeric(format(as.Date(mydf$mydate), format="%Y")) 
mydf$month <- as.numeric(format(as.Date(mydf$mydate), format="%m")) 
newcolnames <- c('myvalue1','myvalue2') 

for (i in seq_along(newcolnames)) { 
    print(newcolnames[i]) 
    mydf$myxts <- xts(mydf[, newcolnames[i]], order.by = mydf$mydate) 
    ## Calculate change over same month in previous year 
    mylag <- 12 
    mydf[, paste(newcolnames[i], "_yoy", sep = "", collapse = "")] <- as.numeric(diff(mydf$myxts, lag = mylag)/ lag(mydf$myxts, mylag)) 
    ## Calculate change over previous month 
    mylag <- 1 
    mydf[, paste(newcolnames[i], "_mom", sep = "", collapse = "")] <- as.numeric(diff(mydf$myxts, lag = mylag)/ lag(mydf$myxts, mylag)) 

    ## Calculate cumulative figure 
    #mydf$newcol <- as.numeric(mydf$myxts) 
    mydf$newcol <- 1 
    mydf <- ddply(mydf, .(year), transform, newcol = cumsum(as.numeric(mydf$myxts))) 
    colnames(mydf)[colnames(mydf)=="newcol"] <- paste(newcolnames[i], "_cuml", sep = "", collapse = "") 

} 

mydf 
+0

Я все еще борюсь с этим. Вызванный вызов ddply представляет собой суммирующее суммирование данных, но только в течение первого года, так что строки в кумулятивно суммированном столбце данных для второго и третьего лет содержат данные cumsum за первый год. Фактически, первый год копируется в последующие годы. Может ли кто-нибудь помочь? – SlowLearner

ответ

0

В вашем цикле, так как myxts не является частью кадра данных, не разделились в заявлении ddply вместе со всем остальным. Измените его на:

mydf$myxts <- xts(mydf[, newcolnames[i]], order.by = mydf$mydate) 

Я не знаю ни одного способа, чтобы использовать динамически генерируемые имена с transform.

+0

спасибо за ответ. Я переместил объект xts в фрейм данных, но теперь я получаю: 'Ошибка в data.frame (список (mydate = c (14730, 14761, 14791, 14822, 14853,: ) аргументы подразумевают различное количество строк: 8, 24', который, как представляется, связан с присваиванием 'newcol ='. – SlowLearner

+0

Это было разрешено путем принудительного ввода объекта xts в числовое значение перед передачей его в ddply. – SlowLearner