2017-08-22 11 views
0

私はフォルダ内に複数のcsvファイルを持っています。各ファイルはファイル名の日付を持っています。私はユーザー定義の開始日と終了日に基づいてデータを抽出しようとしています。私は、次のコードをここR - 複数のファイルを効率的に読む方法

#Method1 
f <- list.files("C:/Fileloc") 
d <- data.frame() 

#start and end dates are user inputs from Shiny 
startdate = as.POSIXct("2015-10-01") 
enddate = as.POSIXct("2016-09-30") 

for(i in 1: length(f)){ 
    filedate <- as.POSIXct(substr(f[i],5,14)) #File name example: XYZ_2015-10-05_ABCD.csv 

    if(between(filedate,startdate, enddate)) { 
    d<-rbind(d, fread(paste("C:/Fileloc",f[[i]],sep = "/"), sep = ";", header = FALSE, 
        blank.lines.skip = TRUE)) 
    } 
} 

に持って、それはこのサイト上のクイック検索は、と言った溶液に私を導いた

user system elapsed 
79.56 29.05 108.60 

(この場合は366個のファイル)すべてのファイルを読み込むのにかかる時間の長さですすべてのファイルを1つの.RDSファイルにまとめてサブセット化する方が簡単です。私はそれを行うには、次のコードを使用します。

#Method2 
saveRDS(d, file = "Alldata.RDS") #d is the same data frame from Method1 

dat <- readRDS("Alldata.RDS") 
colnames(dat) <- c("Col1", "Date","Col3","Col4") 

library(dplyr) 
dat<-filter(dat, between(as.POSIXct(dat$Date, format = "%m/%d/%Y"), 
         as.POSIXct("2015-10-01"), as.POSIXct("2016-09-30"))) 

これがこの手順を実行するために必要な処理です。

user system elapsed 
    58.81 0.36 59.24 

事がある唯一の数日は、日付の範囲内にある場合は、最初の方法がより速くなるでしょう。一方で、それは、第二の方法にかかわらず、開始日と終了日の同じ時間がかかります。私は毎回全データを検索しているので、起こっていると思います。

データをより効率的に読み込み/サブセット化する方法があるのでしょうか?私が.rdsに保存する前にファイルを順番にrbindingしているので、.rdsファイルの日付列はすでに日付順にソートされているはずです。私たちは何とかフィルタリング中にそれを利用することができますか?

+0

読み書き速度が気になる場合は、 'saveRDS(...、compress = FALSE)'を使用します。作成する選択肢は2つあります。ファイルを個別にまたはまとめて保存し、ファイルをRDSまたはテキストとして保存します。これら2つの選択肢を個別に検討してください。 1つのファイルに対して 'fread'や' readRDS'を使う方が速いかどうかを調べるためのテストをしてください。次に、そのメソッドのパフォーマンスが毎回すべてのデータを読み込むのに十分な速さであるかどうか、または個々のファイルを持つ方が必要なものだけを読み込んで結合できるようにするかどうかを決定します。 – Gregor

+0

それほど変わったわけではありません。とにかく、私は、クライアントが主に一度に3ヶ月以上のファイルを実行していないことを知りました。だから、私は最初の方法で行った。ありがとう! – Sujith

答えて

0

はまだ投稿にコメントすることはできませんので、私はここに答えるよ - サブセット化のためのより高速な方法はdata.table形式を使用することです:dは法1を使用して保存され、あなたが既に持っているとき

d[Date %in% start_date:end_date, .(Col1, Date, Col3, Col4),] 

つまり。私は二重引用符の代わりに名前だけで列を参照するほうがずっと簡単です。

method1自体については、forループの代わりにapplyファミリの関数を使用するほうが高速です。 1つの関数を使用してすべてのファイル名を解析し、条件(開始日、終了日)に一致する名前のベクトルを取得し、lapply(file_names, read_function)を使用してすべてのデータを読み取ります。