2016-10-30 13 views
0

중첩 된 for 루프를 두 개의 중첩 된 foreach 루프로 변환하여 일치하는 전제 조건에 따라 데이터 프레임의 값을 변경하려고합니다. 내가 프로세스를 상당히 빠르게 할 수 있다고 믿는 이유.데이터 프레임의 값을 변경하는 중첩 된 foreach 루프 R

library(foreach) # for loop to parallelize 
library(doMC) # create the number of cores to use 

# set the number of cores to use 
registerDoMC(22) # number of CPU cores 

file_list <- c("a", "b", "c") 
ldf <- c(data.frame(Date = c("2016-10-01", "2016-10-02", "2016-10-03", "2016-10-04")), 
    data.frame(Date = c("2016-10-07", "2016-10-08", "2016-10-09")), 
    data.frame(Date = c("2016-10-15", "2016-10-16", "2016-10-17", "2016-10-18", "2016-10-19"))) 

DF <- data.frame(Date = seq(as.POSIXct("2016-10-01", tz = "UTC"), as.POSIXct("2016-10-31", tz = "UTC"), by = 'day'), 
      A = 0, 
      B = 0, 
      C = 0) 

DF2 <- DF # DF2 is used to compare my attempt result 


for (i in 1:length(file_list)) 
{ 
    Date <- ldf[[i]] 
    Date <- as.POSIXct(Date, tz = "UTC") 

    for (j in 1:length(Date)) 
    { 
    ROW <- which(DF$Date == Date[j]) 
    DF[ROW,i+1] <- 1 
    } 

} 

throwaway <- foreach (i = 1:length(file_list)) %dopar% 
{ 
    Date <- ldf[[i]] 
    Date <- as.POSIXct(Date, tz = "UTC") 

    foreach (j = 1:length(Date)) %do% 
    { 
    ROW <- which(DF2$Date == Date[j]) 
    DF2[ROW,i+1] <- 1 
    return(NULL) 
    } 
} 

filelist 내가

ldf

에 읽고있다 파일 목록이 두 변수는

읽을 수있는 파일을 저장하는 데 사용되는 변수입니다 : 다음은 내 코드의 예입니다 이 예제에서는 재현 가능한 예제 만 만들었습니다.

DF는 내 시도 시도는하고

내가 찾고 있어요 출력 저장되는 위치를 foreach에 의해 만들어진 값의 변화가

DF2 루프 저장 DF의입니다려고하고있는 곳입니다 , DF2은 변경되지 않습니다. foreach 루프는 반환 값을 위해 설계된 것으로 알고 있지만 반환 값을 데이터 프레임의 값을 변경해야하는 위치와 일치 시키려면 어떻게해야합니까? 이 값은 file_list에있는 각 파일의 날짜가 데이터 프레임 DF2의 날짜와 일치하는 곳입니다. 일치하는 경우 1은 행 (날짜) 및 열 (파일 이름)의 특정 위치에 배치됩니다. 어떤 도움을 주셔서 미리 감사드립니다!

원하는 출력은 다음과 같습니다

> DF 
      Date A B C 
1 2016-10-01 1 0 0 
2 2016-10-02 1 0 0 
3 2016-10-03 1 0 0 
4 2016-10-04 1 0 0 
5 2016-10-05 0 0 0 
6 2016-10-06 0 0 0 
7 2016-10-07 0 1 0 
8 2016-10-08 0 1 0 
9 2016-10-09 0 1 0 
10 2016-10-10 0 0 0 
11 2016-10-11 0 0 0 
12 2016-10-12 0 0 0 
13 2016-10-13 0 0 0 
14 2016-10-14 0 0 0 
15 2016-10-15 0 0 1 
16 2016-10-16 0 0 1 
17 2016-10-17 0 0 1 
18 2016-10-18 0 0 1 
19 2016-10-19 0 0 1 
20 2016-10-20 0 0 0 
21 2016-10-21 0 0 0 
22 2016-10-22 0 0 0 
23 2016-10-23 0 0 0 
24 2016-10-24 0 0 0 
25 2016-10-25 0 0 0 
26 2016-10-26 0 0 0 
27 2016-10-27 0 0 0 
28 2016-10-28 0 0 0 
29 2016-10-29 0 0 0 
30 2016-10-30 0 0 0 
31 2016-10-31 0 0 0 
+0

당신이이 부분을 설명 할 수 없습니다 : 전부로는 all.equal와 아래 원래 DF와 정확히 일치하는 결과를 보여? 어쩌면 원하는 결과의 예를들 수 있습니까? –

+0

물론! 필자가 찾고자하는이 값들은'file_list'에서 읽은 각 파일의 날짜가 데이터 프레임'DF2'의 날짜와 일치하는 곳입니다. 일치하는 경우 1은 행 (날짜) 및 열 (파일 이름)의 특정 위치에 배치됩니다. – lurodrig

답변

0

제로 루프를 사용하는 것을 고려 있지만 dataframe 목록의 모든 DF 항목에 걸쳐 mergeReduce(). 그러나 데이터 프레임을 설정하고 약간 다른 목록을 작성해야합니다.

먼저 목록의 첫 번째 엘멘 트로 순차적으로 Date 데이터 프레임을 추가하십시오. 그런 다음 읽어들이는 각 파일에 A, B, C에 해당하는 두 번째 열을 추가하십시오 (이 과정은 읽기 과정에서 사용 된 lapply 또는 for 루프에서 수행 할 수 있습니다.이 부분은 데모 용입니다). ". 반환 값이 dataframe의 값을 변경해야하는 위치의 위치와 일치 얻을"

# INITIALIZE LIST WITH DATE SEQUENCE DF 
newldf <- list(data.frame(Date = as.factor(seq(as.POSIXct("2016-10-01", tz = "UTC"), 
            as.POSIXct("2016-10-31", tz = "UTC"), 
            by = 'day')))) 

# APPEND LIST OF DATA FRAMES THAT ARE READ IN, EACH WITH SECOND COL = 1 
newldf <- append(newldf, 
       list(data.frame(Date = c("2016-10-01", "2016-10-02", 
             "2016-10-03", "2016-10-04"), A = 1), 
        data.frame(Date = c("2016-10-07", "2016-10-08", 
             "2016-10-09"), B = 1), 
        data.frame(Date = c("2016-10-15", "2016-10-16", 
             "2016-10-17", "2016-10-18", "2016-10-19"), C=1))) 

# MERGE ALL DATA FAMES TOGETHER 
newDF <- Reduce(function(...) merge(..., by=c("Date"), all=T), newldf) 
newDF[is.na(newDF)] <- 0        # CONVERT NAs TO ZEROs 
newDF$Date <- as.POSIXct(newDF$Date, tz = "UTC")  # CONVERT DATE TO POSIXct 
str(newDF) 
# 'data.frame': 31 obs. of 4 variables: 
# $ Date: POSIXct, format: "2016-10-01" "2016-10-02" ... 
# $ A : num 1 1 1 0 0 0 0 0 0 0 ... 
# $ B : num 0 0 0 0 0 0 1 1 1 0 ... 
# $ C : num 0 0 0 0 0 0 0 0 0 0 ... 

str(DF) 
# 'data.frame': 31 obs. of 4 variables: 
# $ Date: POSIXct, format: "2016-10-01" "2016-10-02" ... 
# $ A : num 1 1 1 0 0 0 0 0 0 0 ... 
# $ B : num 0 0 0 0 0 0 1 1 1 0 ... 
# $ C : num 0 0 0 0 0 0 0 0 0 0 ... 

all.equal(DF, newDF) 
# [1] TRUE 
+0

매우 유망 해 보인다! 그러나 추가하는 날짜의 길이가 같지 않으면 무엇을 제안 하시겠습니까? 그게 내가 일하고 불행히도, 추가 프로세스가 그 시점에서 휴식. 나는 원래의 대답과 이것을 반영하기위한 최종 목표에서 나의 목록을 업데이트했다. 똑바로 생각하고 똑같은 양의 데이트를하지 않는 것에 대해 사과드립니다. – lurodrig

+0

Merge는'all = T' 인수 또는 기본적으로 외부 조인을 사용하므로 목록의 개별 데이터 프레임 길이는 문제없이 변경 될 수 있습니다. 불평등 한 길이로 목록을 업데이트하고 오류없이 실행했습니다. 깨는 것에 대해 당신이 의미하는 바가 확실하지 않습니다. – Parfait

+0

사과! 내 데이터 파일 중 하나에 값이 없으며 추가 기능이 중단됩니다. 나는 당신의 솔루션을 성공적으로 복제 할 수있었습니다. 모든 도움에 감사드립니다! – lurodrig