【问题标题】:pairwise operations on data.tabledata.table 上的成对操作
【发布时间】:2020-10-20 22:17:03
【问题描述】:

我正在尝试计算列对之间的相关性,然后在所有列上拟合 n 个线性模型以预测所述相关性,然后预测相关性(然后使用它们生成相关的随机 a、b、c、d、 e 但这并不重要)。
我已经做了。但是现在代码真的是重复的,我想知道如何以动态的方式来避免代码中的重复。我正在使用data.table,因为性能是关键,因为表可能很大。
这就是我目前所拥有的:

data <-
  data.table(a = rnorm(20),
             b = rnorm(20),
             c = rnorm(20),
             d = rnorm(20),
             logret_a = rnorm(20),
             logret_b = rnorm(20),
             logret_c = rnorm(20),
             logret_d = rnorm(20))

corr <- function(y) cor(y[, 1], y[, 2])
corperiod <- 3

#1 here i would like one line instead of one line per ab, ac, ad, bc, bd
data$cor_ab <- c(NA, zoo::rollapplyr(data[-1, .(logret_a, logret_b)], corperiod, corr, by.column = FALSE, fill = NA))
data$cor_ac <- c(NA, zoo::rollapplyr(data[-1, .(logret_a, logret_c)], corperiod, corr, by.column = FALSE, fill = NA))
data$cor_ad <- c(NA, zoo::rollapplyr(data[-1, .(logret_a, logret_d)], corperiod, corr, by.column = FALSE, fill = NA))
# and so on...

#2 here i would like two lines instead of two lines per ab, ac, ad, bc, bd
fit_cor_ab <- lm(data=data, cor_ab ~ a + b + c + d + logret_a + logret_b + logret_c +  logret_d)
fit_cor_ab <- MASS::stepAIC(fit_cor_ab, direction="both", trace = FALSE)

fit_cor_ac <- lm(data=data, cor_ac ~ a + b + c + d + logret_a + logret_b + logret_c +  logret_d)
fit_cor_ac <- MASS::stepAIC(fit_cor_ac, direction="both", trace = FALSE)
# and so on...

simul <- as.data.table(matrix(0, nrow=100, ncol=ncol(data)))
colnames(simul) <- colnames(data)
simul[1] <- data[1]
# skipping for loop
i <- 2
#3 here i would like one line instead of one line per ab, ac, ad, bc, bd
simul[i, cor_ab := predict(fit_cor_ab, newdata = simul[i-1])]
simul[i, cor_ac := predict(fit_cor_ac, newdata = simul[i-1])]
# and so on...

我想要的是有一种方法可以对data.tabledata 中的任意数量的列执行 #1、#2 和 #3 中标记的这 3 个操作,并且无论data 中列的名称。我的代码有效...只是我必须在任何时候更改data 的内容时对其进行修改,所以这不太好...

任何帮助表示赞赏!

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    似乎是简单函数和嵌套 for 循环的理想选择。你尝试过这样的事情吗?注意calculate_cor 函数修改了data,所以你不需要返回任何东西。

    # correlations
    calculate_cor <- function(x, y){
      corr <- function(y) cor(y[, 1], y[, 2])
      corperiod <- 3
      newcol <- paste0("cor_", x, y)
      x <- paste0("logret_", x)
      y <- paste0("logret_", y)
      tmp <- data[-1, .SD, .SDcols=c(x, y)]
      out <- zoo::rollapplyr(tmp, corperiod, corr, 
                             by.column=FALSE, fill = NA)
      data[, (newcol) := c(NA, out)]
    }
    
    cols <- c("a", "b", "c", "d")
    for (x in cols) {
      for (y in cols) {
        if (x < y) {
          calculate_cor(x, y)
        }
      }
    }
    
    # regressions
    fit <- list()
    cols <- grep("cor_", colnames(data), value=TRUE)
    for (x in cols) {
      f <- as.formula(paste(x, "~a+b+c+d+logret_a+logret_b+logret_c+logret_d"))
      mod <- lm(f, data)
      fit[[x]] <- MASS::stepAIC(mod, direction="both", trace=FALSE)
    }
    

    我不太明白你想通过第三步完成什么,但希望与上述相同的逻辑适用。

    【讨论】:

    • 嘿文森特,谢谢你。是的,步骤#3 for (x in corcolnames) { simul[i, (x) := predict(fit[[x]], newdata = simul[i - 1])] } FYC 在同一行上的东西,为了精确步骤#3,因为我不清楚:目标是使用拟合线性模型来预测相关性,然后从那时起我会生成一些相关日志返回,然后返回实际值。希望它能澄清
    • 最后一步。感谢您的解决方案!
    猜你喜欢
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    相关资源
    最近更新 更多