2017-04-24 14 views
3

複数のcsvファイルを1つのデータフレームにマージし、forループを使用して結果のデータフレームを操作しようとしています。得られたデータフレームは、1,500,000〜2,000,000行の間の任意の場所にある可能性があります。Forループをネストされた状態でRの場合

私は以下のコードを使用しています。

setwd("D:/Projects") 
library(dplyr) 
library(readr) 
merge_data = function(path) 
{ 
    files = dir(path, pattern = '\\.csv', full.names = TRUE) 
    tables = lapply(files, read_csv) 
    do.call(rbind, tables) 
} 


Data = merge_data("D:/Projects") 
Data1 = cbind(Data[,c(8,9,17)],Category = "",stringsAsFactors=FALSE) 
head(Data1) 

for (i in 1:nrow(Data1)) 
{ 
    Data1$Category[i] = "" 
    Data1$Category[i] = ifelse(Data1$Days[i] <= 30, "<30", 
         ifelse(Data1$Days[i] <= 60, "31-60", 
         ifelse(Data1$Days[i] <= 90, "61-90",">90")))  

} 

ただし、コードは非常に長く実行されています。同じ操作を行うより速く、より速い方法がありますか?

答えて

2

freaddata.tableから読み取り、次にcut/findIntervalを使用してこれを最適化することができます。それは複数のコアで実行されたときにこれがより顕著になり、freadは、すべてのノードを利用して、サーバー上のノードは、すでにdplyrを使用している平行

library(data.table) 
merge_data <- function(path) { 
    files = dir(path, pattern = '\\.csv', full.names = TRUE) 
    rbindlist(lapply(files, fread, select = c(8, 9, 17))) 
} 

Data <- merge_data("D:/Projects") 
Data[, Category := cut(Data1, breaks = c(-Inf, 30, 60, 90, Inf), 
     labels = c("<=30", "31-60", "61-90", ">90"))] 
+1

おかげで多くのことを実行します!コードはちょうどうまく動作し、数秒未満で走った:) –

1

を実行し、なぜだけでなく:

Data = merge_data("D:/Projects") %>% 
    select(8, 9, 17) %>% 
    mutate(Category = cut(Days, 
         breaks = c(-Inf, 30, 60, 90, Inf), 
         labels = c("<=30", "31-60", "61-90", ">90")) 
0

Akrunは確かにfreadが実質的に速いread.csvです。

しかし、彼の投稿に加えて、あなたのforループはまったく必要ないと付け加えます。彼はそれをcut/findIntervalに置き換えました。私は慣れていません。単純なRプログラミングの観点からは、計算のある要素が行ごとに変化するときにforループが必要です。しかし、あなたのコードでは、そうではなく、forループの必要はありません。

本質的に、列を1回だけ計算する必要がある場合は、計算を最大200万回実行しています。

あなたはこのような何かをループのためにあなたを置き換えることができます。

Data1$category = ifelse(Data1$Days <= 30, "<=30", 
       ifelse(Data1$Days <= 60, "31-60", 
       ifelse(Data1$Days <= 90, "61-90",">90"))) 

とあなたのコードはwaaaaaay速く

関連する問題