如何在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 而不是使用 rbind
或 cbind
也是一个好主意。
尽管在 R 中动态创建数据帧不是一个好习惯(您应该像其他答案一样将它们放在列表中),但这样做的方式是使用 assign
和 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))
既然你说你的计算速度慢,我想为你提供一个并行的解决方案。如果你有一台现代计算机,它可能有 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)
完成后停止并关闭集群。
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 而不是使用 rbind
或 cbind
也是一个好主意。
尽管在 R 中动态创建数据帧不是一个好习惯(您应该像其他答案一样将它们放在列表中),但这样做的方式是使用 assign
和 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))
既然你说你的计算速度慢,我想为你提供一个并行的解决方案。如果你有一台现代计算机,它可能有 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)
完成后停止并关闭集群。