2016-12-18 3 views
0

나는 꽤 많은 시간 동안 data.table을 가진 다중 루프를 다루려고 노력하고 좌절감을 느꼈다. SQL을 사용하면 매우 직관적 인 부분이 있지만 R을 사용하면 몇 가지 문제가 발생합니다.R에있는 data.table을 가진 다중 루프

예를 들어, 하나의 txt 파일을 자유롭게하고 싶습니다. (파일이 수백 개 정도되고, 각 1GB 정도입니다.) 계산을하십시오 (합계 가격과 퀀트, 시간이 my.time이고 일부는 isin입니다. my.time, isin 및 price로 그룹화), 결과를 일부 CSV 파일에 기록하고 R 메모리에서 원래 txt 파일을 제거합니다. 그런 다음 모든 txt 파일에 대해 이러한 계산을 하나씩 다시 실행하고 출력 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") 

나는이 두 간단한 루프를 시도 :

는 예를 들어, 데이터 (그림 아주 작은, 단지 두 개의 동일한 파일)로 시작하자

 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) 
     }} 

두 번째 편집 : j와 루프가 마침내 나를 위해 일하기 시작했습니다 (굵게 표시된 부분 때문에). 어쩌면 for 루프없이 작업하여 동일한 결과를 얻을 수있을 것입니다.

도움 주셔서 대단히 감사드립니다.

+0

어느 지점에서 작동하지 않습니까? 코드에서 경고 및 오류를 읽었습니까? – jangorecki

+0

예, 처음에는 다음 메시지가 표시됩니다. '[.data.table' (dt, % my.isin 및 time> my.time의 isin %) 오류 : 'by '또는 'keyby'리스트는 length (86401,1,86401)이고, 각각은 x의 행이나 i (0)가 반환 한 행의 길이와 같아야합니다. ' – Linas

+0

자,'j '의 사용에 대해 불평하고 있습니다. 'by' 아마도 당신은 돌아가서 거기서 무엇을하려고했는지 생각할 필요가있을 것입니다. (당신의 코드의 대부분은 내가 보통 보는 것과는 아주 다르기 때문에 실제로 얻지는 않습니다.) – Frank

답변

2

문제는 which 문 출력이 0 행을 반환한다는 것입니다. 먼저 시간을 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 또는 사용자 정의 시간보다 큰 time5하여 필터링 할 수 있습니다?

+0

감사합니다 theArun! 그러나 당신의 예에서 t1은 무엇을 의미합니까? – Linas

+0

아, 죄송합니다. 그것은'시간입니다. – theArun

+0

다시 한번 감사드립니다.그러나 시간을 "데이터"테이블에없는 "외부"벡터와 비교해야합니다 (원래 데이터로이 방법으로 작업해야 함). 즉, 두 번째 단계 (시간 5 생성)를 수행하지 않아도됩니다. (우리는 단순함을 위해 isin을 제거 할 수있다) : 'my.time <-format (seq.POSIXt as.POSIXct (Sys.Date()), as.POSIXct (Sys.Date() + 1), by = % ("5 분"), "% H : % M : % S")' 그리고 dt [, (sprice = sum (price), squant = sum (quant) 하지만이 오류가 다시 나타납니다 : 'by'또는 'keyby'목록의 길이는 길이 (289,86401)입니다. 각각 길이가 같아야합니다 ... ' – Linas

관련 문제