2016-10-30 12 views
0

Я пытаюсь преобразовать два вложенных цикла для двух вложенных циклов foreach, чтобы изменить значения фрейма данных на основе соответствующих предварительных условий. Причина в том, что я считаю, что могу значительно ускорить процесс. Ниже приведен пример моего кода:Вложенные значения изменения петли foreach в dataframe 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, совпадает с датами в dataframe 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

Не мог бы вы объяснить эту часть: «получить возвращаемые значения в соответствии с расположением, где значения dataframe должны измениться.»? Может быть, вы можете привести пример вашего желаемого результата? –

+0

Конечно! Эти значения, которые я ищу, - это дата, в которой дата каждого файла, считанного в 'file_list', совпадает с датами в DataFrame' DF2'. Если они совпадают, то 1 помещается в это конкретное местоположение строки (Дата) и столбца (Имя файла). – lurodrig

ответ

0

Рассмотрите возможность использования нулевых циклов, но Reduce() с merge по всем пунктам ФР списка dataframe. Однако вам необходимо настроить свои фреймы данных и немного изменить их.

Прежде всего, добавьте в качестве первого списка список последовательных Date dataframe. Затем в каждом файле, который вы читаете, добавьте второй столбец, соответствующий A, B, C, каждый из которых равен одному (что можно сделать в цикле или for, используемом при считывании в процессе -постановить эту часть для демонстрации). В целом, как показано ниже с all.equal точными результатами матча с оригинальным DF:

# 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