如何在for循环中存储来自for循环的数据? (r 中的滚动相关)

How to store data from for loop inside of for loop? (rolling correlation in r)

require(quantmod)
require(TTR)

iris2 <- iris[1:4]
b=NULL
for (i in 1:ncol(iris2)){
for (j in 1:ncol(iris2)){
a<- runCor(iris2[,i],iris2[,j],n=21)
b<-cbind(b,a)}}

我想计算数据框中不同列的滚动相关性,并按列单独存储数据。虽然上面的代码将数据存储到变量 b 中,但它并没有那么有用,因为它只是转储所有结果。我想要的是能够为每个 i 创建不同的数据框。

在这种情况下,因为我有 4 列,所以我最终想要的是 4 个数据帧,每个数据帧包含 4 列显示滚动相关性,即 df1 = corr of col 1 vs col 1,2,3,4, df2 = col 2 与 col 1,2,3,4...等的更正)

我想过用lapply或rollapply,但是运行变成了同样的问题。

d=NULL
for (i in 1:ncol(iris2))
 for (j in 1:ncol(iris2))
{c<-rollapply(iris2, 21 ,function(x) cor(x[,i],x[,j]), by.column=FALSE)
d<-cbind(d,c)}  

非常感谢任何意见。

如果你想保留展开的循环,数据帧列表怎么样?

e <- list(length = length(ncol(iris2)))

for (i in 1:ncol(iris2)) {
  d <- matrix(0, nrow = length(iris2[,1]), ncol = length(iris2[1,]))
    for (j in 1:ncol(iris2)) {
        d[,j]<- runCor(iris2[,i],iris2[,j],n=21)
    }
e[[i]] <- d
}

用占位符分配你想要的 space 数量并将项目放入 space 而不是使用 rbindcbind 也是一个好主意。

尽管在 R 中动态创建数据帧不是一个好习惯(您应该像其他答案一样将它们放在列表中),但这样做的方式是使用 assignget 函数。

for (i in 1:ncol(iris2)) { 
   for (j in 1:ncol(iris2)){
      c <-  runCor(iris2[,i],iris2[,j],n=21)

      # Assign 'c' to the name df1, df2...
      assign(paste0("df", i), c)
      }
}

# to have access to the dataframe:
get("df1")

# or inside a loop
get(paste0("df", i))

既然你说你的计算速度慢,我想为你提供一个并行的解决方案。如果你有一台现代计算机,它可能有 2 个内核,如果不是 4 个(或更多!)。您可以通过以下方式轻松查看:

require(parallel) # for parallelization
detectCores()

现在代码:

require(quantmod)
require(TTR)

iris2 <- iris[,1:4]

并行化需要将函数和变量置于一个特殊的环境中,该环境随每个进程一起创建和销毁。这意味着必须创建一个包装函数来定义变量和函数。

wrapper <- function(data, n) {
  # variables placed into environment
  force(data)
  force(n)

  # functions placed into environment
  # same inner loop written in earlier answer
  runcor <- function(data, n, i) {
    d <- matrix(0, nrow = length(data[,1]), ncol = length(data[1,]))
    for (j in 1:ncol(data)) {
      d[,i] <- TTR::runCor(data[,i], data[,j], n = n)
    }
    return(d)
  }

  # call function to loop over iterator i
  worker <- function(i) {
    runcor(data, n, i)
  }

  return(worker)
}

现在在您的本地计算机上创建一个集群。这允许多个核心分别运行。

parallelcluster <- makeCluster(parallel::detectCores())
models <- parallel::parLapply(parallelcluster, 1:ncol(iris2),
                              wrapper(data = iris2, n = 21))
stopCluster(parallelcluster)

完成后停止并关闭集群。