【问题标题】:plyr along two dimensions (ddply)plyr 沿二维 (ddply)
【发布时间】:2011-11-29 23:24:49
【问题描述】:

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

date id value
d1 id1 v1
d2 id1 v2
d1 id2 v3
d2 id2 v4

我想通过 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)

然后我打算用

重新组装所有东西
ldply(models, function(x) {summary(x)$r.squared})

这不起作用,因为 models 是一个列表列表,而 x 是一个模型列表。但是,如果我的 function(x) 通过 cat 返回一个列表,将所有 rsquared 放入一个列表中,我会收到一个错误,因为 ldply 期望 function(x) 返回一个原子结果。非常感谢您的帮助。

【问题讨论】:

    标签: list r dataframe plyr


    【解决方案1】:

    这个 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
    

    希望这能回答你的问题。

    【讨论】:

    • 另外,有没有一种方法可以让我也保留日期,以便将它们与此处的 coefs 一起输出?
    【解决方案2】:

    你不能这样做

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

    基本上,由于您的 x 是一个模型列表,因此请在此基础上再做一次 l*ply。我不确定返回值是否正确,因为它不可重现。

    【讨论】:

    • 这实际上是我尝试做的事情之一,但它看起来好像 ldply 期望你的函数的输出是原子的而不是列表......这对我来说似乎很奇怪但可能有意义因为它试图将每个条目转换为数据框中的一行..?
    【解决方案3】:

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

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

    这只会返回一个 r.squared 向量,您必须重新创建数据框。

    【讨论】:

    • 似乎 raply 不是 lapply 的递归版本,而是运行您传递给它的表达式的副本。
    猜你喜欢
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 2018-05-12
    • 2014-11-05
    • 2012-08-18
    相关资源
    最近更新 更多