R:在数据帧列上的循环中使用ddply

问题描述:

我需要根据数据框中列的子集中每列中的值计算并向数据帧添加多个新列。这些列都包含时间序列数据(有一个共同的日期列)。例如,我需要为十几列计算上一年同月的变化。我可以指定它们并单独计算它们,但是对于大量的列进行转换变得繁重,所以我试图用for循环自动化该过程。R:在数据帧列上的循环中使用ddply

我做得不错,直到我尝试使用ddply为目前为止的年份的运行总计创建一列。 ddply会在循环的每次迭代期间添加新行,并在cumsum计算中包括这些新行。我有两个问题。

问:如何获得ddply来计算正确的cumsum? 问:如何在ddply调用期间指定列的名称,而不是使用虚拟值并在之后进行重命名?

[编辑:我说话太快,下面的更新的代码不会在这一点上工作,只是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

在你的循环,因为myxts不是数据帧的一部分,它不是与其他所有内容一起在ddply声明中分解。将其更改为:

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

我不知道任何方式与transform使用动态生成的名称。

+0

感谢您的回复。我已经将xts对象移动到数据框中,但是现在我得到:'Data.frame中的错误(list(mydate = c(14730,14761,14791,14822,14853,: arguments)意味着不同的行数:8, 24',似乎与'newcol ='赋值有关 – SlowLearner

+0

这是通过在将xts对象传递给ddply之前强制将其转换为数字来解决的。 – SlowLearner