List 沿二维方向的plyr(ddply)

List 沿二维方向的plyr(ddply),list,r,dataframe,plyr,List,R,Dataframe,Plyr,我有一个数据框,看起来像这样(为了说明而简化): 我想按id将其分开,在每个id上运行一个滚动回归(因此每个id将有N个回归),选择rsquared并将其组装回一个数据帧。我的方法是: roll_reg <- function(df) { T <- with(df, min(nlen(xs_ret), nlen(xs_mkt), nlen(smb), nlen(hml), nlen(umd))) OFFSET <- 3 themodels <-

我有一个数据框,看起来像这样(为了说明而简化):

我想按id将其分开,在每个id上运行一个滚动回归(因此每个id将有N个回归),选择rsquared并将其组装回一个数据帧。我的方法是:

roll_reg <- function(df) {
    T <- with(df, min(nlen(xs_ret), nlen(xs_mkt), nlen(smb), nlen(hml), nlen(umd)))
    OFFSET <- 3

    themodels <- as.list(rep(NA, OFFSET))
    #120 days rolling period
    if (T>OFFSET) {
        #the first OFFSET models are na

        for (i in seq(OFFSET+1, T)) {
            idx <- seq(i-OFFSET-1,i)
            themodels[i] <- list(with(df, 
                      lm(xs_ret[idx]~xs_mkt[idx]+smb[idx]+hml[idx]+umd[idx])))

        }

        return(themodels)
    }
    else { return(NA) }
}

models <- dlply(dt_df, "id", roll_reg)
这不起作用,因为模型是列表列表,而x是模型列表。但是,如果我的
函数(x)
通过
cat
-ing将所有的r分成一个列表返回一个列表,我会得到一个错误,因为
ldply
期望
函数(x)
返回一个原子结果。非常感谢您的帮助。

您不能这样做吗

ldply(models, laply, function(x) {summary(x)$r.squared})

基本上,因为你的
x
是一个模型列表,所以在上面再做一次l*ply。我不确定返回值是否正确,因为它是不可复制的。

您可以尝试
rappy
,它是
lappy
的递归版本。你可以试试这样的

rapply(models, function(model) summary(model)$r.squared)

这将只返回r.squared的向量,您必须重新创建数据帧。

此r代码再现了问题:

library(plyr)

dat = data.frame(date = rep(paste("d", 1:100, sep = ""), length = 100),
             id = rep(paste("id", 1:10, sep = ""), each = 100),
             value = runif(100))

make.lm = function(input) {
  lm1 = lm(value~date, input[1:50,])
  lm2 = lm(value~date, input[1:50,])
  return(list(lm1, lm2))
}

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) summary(x)$r.squared)
# Error in summary(x)$r.squared : $ operator is invalid for atomic vectors
这项工作:

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) 
             ldply(x, function(y) 
              return(data.frame(rsq = summary(y)$r.squared))))
coefs$id2 = rep(1:2, each = 2)

> head(coefs)
    id rsq id2
1  id1   1   1
2  id1   1   1
3 id10   1   2
4 id10   1   2
5  id2   1   1
6  id2   1   1

希望这能回答您的问题。

这实际上是我试图做的事情之一,但ldply似乎希望函数的输出是原子的,而不是列表。。。这对我来说似乎很奇怪,但可能是有意义的,因为它试图将每个条目转换为数据帧中的一行..?raply似乎不是Lappy的递归版本,而是它运行您传递给它的表达式的副本。另外,是否有一种方法可以同时保留日期,以便它们与这里的COEF一起输出?
library(plyr)

dat = data.frame(date = rep(paste("d", 1:100, sep = ""), length = 100),
             id = rep(paste("id", 1:10, sep = ""), each = 100),
             value = runif(100))

make.lm = function(input) {
  lm1 = lm(value~date, input[1:50,])
  lm2 = lm(value~date, input[1:50,])
  return(list(lm1, lm2))
}

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) summary(x)$r.squared)
# Error in summary(x)$r.squared : $ operator is invalid for atomic vectors
models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) 
             ldply(x, function(y) 
              return(data.frame(rsq = summary(y)$r.squared))))
coefs$id2 = rep(1:2, each = 2)

> head(coefs)
    id rsq id2
1  id1   1   1
2  id1   1   1
3 id10   1   2
4 id10   1   2
5  id2   1   1
6  id2   1   1