2016-07-21 1 views
0
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에 대해 서로 다른 데이터 프레임을 만들 수 있다는 것입니다.for 루프에서 for 루프의 데이터를 저장하는 방법은 무엇입니까? (r 롤링 상관)

이 경우, 필자가 궁극적으로 원하는 것은 4 개의 데이터 프레임입니다. 각각 4 개의 열이 롤링 상관 관계를 표시합니다. 즉, df1 = col1 대 col1 대 col1,2,3,4, df2 = col 2 대 cor 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)} 

모든 입력에 정말 감사하겠습니다.

+0

인덱스 벡터에 'foreach' 루프 또는 mapply를 시도하십시오. DF 목록의 목록을 보여 줄 것입니다. 'i''와'j' 그리고'c & d'에 의해 중첩 됨 – Adam

+0

for 루프에서 cbind를 사용하는 것은 결코 좋은 생각이 아닙니다. 지나치게 메모리에 복사되는 것을 피하려면 사전 정의 된 길이의 목록을 사용하는 것이 훨씬 더 좋습니다. –

답변

2

확장 된 루프를 유지하려면 데이터 프레임 목록은 어떻습니까?

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을 사용하는 것이 좋습니다. 이 R의 비행 (다른 대답으로 목록에 넣어 선호한다)에 dataframes을 만들 수있는 좋은 방법이 하지하지만

+0

제안 해 주셔서 감사합니다. 이 방법에 대해 생각하지 않았고 훌륭하게 작동합니다. 하지만 문제는 내가 실행중인 실제 데이터에 100 열 이상이 있고 코드를 실행하는 데 20 분 이상 걸리는 것처럼 보입니다 ... 간단히 말해서 모든 데이터에 대한 데이터의 롤링 상관 관계를보고 싶습니다. 내 질문에 언급했다. 더 효율적으로 만들 수있는 방법이 있을까요? 다시 한번 감사드립니다. – sh2657

+0

@ sh2657 귀하의 의견이 잘린 것 같습니다. –

+0

죄송합니다. 실수로 엔터를 치고 편집 중이었습니다. 지금 잘해야합니다. – sh2657

2

는, 그렇게 할 수있는 방법은 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)) 
1

계산 속도가 느린 것으로 알려 졌으므로 필자는 병렬 솔루션을 제공하고자했습니다. 현대 컴퓨터를 사용하는 경우 4 개가 아닌 경우 2 개의 코어가있을 것입니다 (이상!).

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) 

완료되면 클러스터를 중지하고 닫습니다.

+0

당신이 최고입니다. 고맙습니다. – sh2657