2016-12-18 6 views
0

私はかなりの時間data.tableで複数のループに対処しようとし、不満を持っています。 SQLではかなり直感的でしたが、Rではいくつかの問題があります。複数のループがdata.table with R

たとえば、1つのtxtファイルをフリーダイヤルしたいのですが(1GBごとに数百のファイルがあるので)、計算を行います(時間がmy.timeのときにsum priceとquantを選択し、 my.time、isin、およびpriceでグループ化)、結果をいくつかのcsvファイルに書き込み、元のtxtファイルをRメモリから削除します。これらの計算をすべてのtxtファイルに対して1つずつやり直し、出力csvファイルを追加します。

 time<-format(seq.POSIXt(as.POSIXct(Sys.Date()), as.POSIXct(Sys.Date()+1), by = "1 sec"),"%H:%M:%S") 
     n<-length(time) 
     isin<-paste("US",1:n,sep="") 
     price<-rnorm(n,101,1) 
     quant<-rnorm(n,5,1) 
     dt<-data.table(time,isin,price,quant) 
     write.table(dt,"raw.txt",append = FALSE,sep = ",",col.names = TRUE, row.names = FALSE) 
     write.table(dt,"raw2.txt",append = FALSE,sep = ",",col.names = TRUE, row.names = FALSE) 

    my.files <- list.files(pattern = "raw*.txt") 
    my.time<-format(seq.POSIXt(as.POSIXct(Sys.Date()), as.POSIXct(Sys.Date()+1), by = "5 min"),"%H:%M:%S") 
    my.isin<-c("US100","US150","US225","US250","US1050") 

その後、私はこれらの2つの単純なループしてみてください:

 for (i in my.files){ 
       for (j in my.time){ 
       dt<-fread(i) 
     write.table(dt[which(isin %in% my.isin & time>j), 
      .(sprice=sum(price),squant=sum(quant),**time.my=j**), by = .(isin,price)], 
      "output.csv",append = TRUE,sep = ",",col.names = TRUE) 
     rm(dt) 
     }} 

第二編集:

は(イラストのためのちょうど2つの同一のファイル、非常に小さい)の例のデータで始めることができます最終的に私のために働くようになったjとのループ(太い部分のため)。おそらくループなしで作業して同じ結果を得ることは可能でしょうか?

ありがとうございました!

+0

この時点ではあなたのためには機能しませんか?あなたのコードに警告やエラーが表示されましたか? – jangorecki

+0

はい、私はこのメッセージを最初に受け取りました: '[.data.table'(dt、%my.isin&time> my.timeのisin%)のエラー: 'by'または ' 'keyby'リストは長さ(86401,1,86401)です。それぞれは、xの行またはi(0)によって返される行の長さと同じ長さでなければなりません。 – Linas

+0

これで 'j 'の使用について不平を言いますあなたが戻って、あなたがそこで何をしようとしているのか考えてみる必要がありますか?(あなたのコードの大部分は、私が通常見ているものと非常に異なるので、実際にはそれを取得しません) – Frank

答えて

2

問題は、which文の出力がゼロ行を返すことです。まず、あなたの時間をtimeタイプに変換します。私は5分のグループ化変数を作成しました。

これは、最初にテーブルを集計します。

dt[,`:=`(time= as.ITime(strptime(time, format="%H:%M:%S")))] 
dt[,`:=`(time5 = format(strptime("1970-01-01", "%Y-%m-%d", tz="UTC") + 
          round(as.numeric(time)/300)*300,"%H:%M"))] 

dt[, list(sprice = sum(price),squant= sum(quant)),by = c("time5","price","isin")][isin %in% my.isin] 


# time5  price isin sprice squant 
# 1: 00:00 102.46668  US1 102.46668 3.002960 
# 2: 00:00 99.02186  US2 99.02186 5.253252 
# 3: 00:00 100.23665  US3 100.23665 6.153950 
# 4: 00:00 102.21466  US4 102.21466 3.461051 
# 5: 00:00 100.97890  US5 100.97890 5.893336 

my.isnでフィルタリングするか、カスタム時間よりも大きい時間5をフィルタリングできますか?

+0

ありがとうtheArun!しかし、あなたの例ではt1は何を意味していますか? – Linas

+0

ああ、申し訳ありません、それは 'time'です – theArun

+0

もう一度ありがとう。しかし、私は、(私は元のデータでこのように動作する必要がある)データテーブルにないいくつかの "外部"ベクトルと時間を比較する必要があります。このようなもの(簡略化のためにisinを削除することができます): 'my.time <-format(seq.POSIXt as.POSIXct(Sys.Date())、as.POSIXct(Sys.Date()+ 1)、by =%(%);%H:%M:%S) " そして' dt [、リスト(sprice = sum(price)、squant = sum(quant) "time"、 "price")] [time> my.time] ' このエラーはもう一度起こります: 'by'または 'keyby'リストの項目は長さ(289,86401)です。それぞれは同じ長さでなければなりません... ' – Linas

関連する問題