如何将来自for循环的数据存储在for循环内? (r中的滚动相关)
Posted
技术标签:
【中文标题】如何将来自for循环的数据存储在for循环内? (r中的滚动相关)【英文标题】:How to store data from for loop inside of for loop? (rolling correlation in r) 【发布时间】:2016-11-25 04:07:19 【问题描述】: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 = col 1 与 col 1、2、3、4 的 corr,df2 = corr col 2 vs 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)
非常感谢任何意见。
【问题讨论】:
在索引向量上尝试foreach
循环或mapply
。它会给你一个 DF 列表的列表。嵌套由 i
然后 j
然后 c&d
在 for 循环中使用 cbind 绝不是一个好主意。使用具有预定义长度的列表以避免在内存中过度复制是更好的做法。
【参考方案1】:
如果你想保持扩展循环,数据帧列表怎么样?
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
使用占位符分配所需的空间量并将项目放入该空间而不是使用rbind
或cbind
也是一个好主意。
【讨论】:
感谢您的建议。没想到这种方式,效果很好。但问题是我正在运行的实际数据有 100 多列,运行代码似乎需要 20 多分钟......我只是想看看数据与所有其他数据的滚动相关性,正如我简要介绍的在我的问题中提到。有什么方法可以提高效率吗?再次感谢。 @sh2657 你的评论好像被删了。 对不起,我不小心按了 Enter 并正在编辑它。现在应该好了。 @sh2657 如果要计算 100 列的相关性,100 次可能需要一段时间。如上所述使用foreach
和mapply
会有所帮助,但仍需要一点时间。
应该检查一下。感谢您的帮助。【参考方案2】:
虽然不是在 R 中动态创建数据框的好习惯(您应该像其他答案一样将它们放在列表中),但这样做的方法是使用 @ 987654321@ 和 get
函数。
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))
【讨论】:
【参考方案3】:既然您说您的计算速度很慢,我想为您提供一个并行解决方案。如果您有一台现代计算机,它可能有 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)
完成后停止并关闭集群。
【讨论】:
你是最棒的。谢谢。以上是关于如何将来自for循环的数据存储在for循环内? (r中的滚动相关)的主要内容,如果未能解决你的问题,请参考以下文章
来自 for 循环内的 AJAX 链中最后一个 AJAX 请求的返回值