2014-12-01 1 views
0

7,000 개가 넘는 파일이 있습니다. * .bil 파일 하나의 * .csv 파일로 병합하고 내보내려고합니다. 나는 래스터 및 as.data.frame를 사용하여 * .bil 파일을 읽을 수 있어요 :여러 * .bil 기후 데이터를 * .csv에 병합

setwd("/.../Prism Weather Data All/") 
filenames <- list.files(path = "/.../Prism Weather Data All/", pattern = ".bil") 
r = raster("PRISM_ppt_stable_4kmM2_189501_bil.bil") 
test <- as.data.frame(r, na.rm=TRUE) 

은이 작업 디렉토리를 설정하고 * .bil 모든 파일을 잡는다. 하지만 하나의 파일을 래스터 화하고 as.data.frame을 설정하여 올바른지 확인합니다. 완벽하게 작동합니다. 하지만 모든 7000 파일 (파일 이름)을 하나로 병합하는 방법을 찾으려고합니다.

이 문제에 도움을 주시면 감사하겠습니다. 미리 감사드립니다. 7000 가정

+0

'values ​​(r)'은 아마도'as.data.frame (r)'보다 빠를 것입니다. – jbaums

+0

as.data.frame (stack (filenames))을 시도해보십시오. 그러나 이것을 처리하는 방법은 많습니다. – mdsumner

답변

1

는 실수하지 근사치이며, 각 파일의 모든 데이터는 동일 구조 (열과 행의 같은 수의)됩니다 : 컴퓨터가이 점을 명심

setwd("/.../Prism Weather Data All/") 

nc<- ## put the number of columns of each file (assuming they're all the same) 
nr<- ## put the number of rows of each file (assuming they're all the same) 

filenames <- list.files(path = "/.../Prism Weather Data All/", pattern = ".bil") 

# initialize what is likely to be a large object 
final.df<-as.data.frame(matrix(NA,ncol=7000*nc,nrow=nr)) 
counter=1 
# loop through the files 
for (i in filenames){ 
    r = raster(i) 
    test <- as.data.frame(r, na.rm=TRUE) 
    final.df[,counter:counter+nc]<-test 
    counter<-counter+nc+1 
} 

# write the csv 
write.csv(final.df,"final-filename.csv") 

을 R이 메모리에 객체를 가져야하므로 모든 데이터를 유지할 수있는 충분한 메모리가 있어야합니다.

열의 수가 파일마다 다른 경우 루프 내에 final.df 할당의 인덱스를 조정하고 이에 따라 counter을 증가시켜 조정할 수 있습니다.


편집 : 예상 된 결과

을 생산하기 위해 나는 for 루프는 작업의 이런 종류의 작업을 수행 할 수있는 유일한 방법에 대해 생각합니다. 실제로 7000 개의 파일은 꽤 큰 세트이므로 반복되는 것을 보면서 시간을 보내고 싶습니다.

setwd("/.../Prism Weather Data All/") 

nc<- ## put the number of columns you expect the data in the files to have 
nr<- ## put roughly the number of rows times 12 (if you plan to read a year worth of data) 
    ## PLUS some tolerance, so you'll end up with an object actually larger than needed 

filenames <- list.files(path = "/.../Prism Weather Data All/", pattern = ".bil") 

# initialize what is likely to be a large object 
final.df<-as.data.frame(matrix(NA,ncol=c,nrow=nr)) 
counter=1 
# loop through the files 
for (i in filenames){ 
    r = raster(i) 
    test <- as.data.frame(r, na.rm=TRUE) 
    numrow2<-nrow(test) 
    final.df[counter:counter+numrow2,]<-test 
    counter<-counter+numrow2+1 
} 

final.df[counter-1:nrow(final.df),]<-NULL ## remove empty rows 

# write the csv 
write.csv(final.df,"final-filename.csv") 

희망이 있습니다.

+0

이것은 처음에 생각한 것이지만, 매우 길어질 것이라는 두려움에서 for 루프를 사용하고 싶지 않았습니다. 시간, 그것은 무엇을하고 있습니다. 나는 이것을 조금씩 실행하고 그것이 어떻게되는지 보게 될 것이다. 당신의 도움을 주셔서 감사합니다. – Vedda

+0

도움을 주셔서 감사합니다. 그러나 이것이 작동하지 않습니다. 필자는 1 년 밖에 걸리지 않았는데 12 개의 파일이 있고 열로 병합하는 대신 36 개의 열이 생성됩니다. – Vedda

+0

여기에 오류가 있습니다.> 오류 : [<-. data.frame' ('* tmp *',, 카운터 : counter + nc, 값 = 목록 (: 새로운 열은 기존 열 뒤에 구멍을 남깁니다 – Vedda

1

필자는 프리즘 데이터로 작업 해 왔으며 아래에서 다른 방법으로이를 수행하고 있습니다. 이것은 7,000 개의 .bil 파일에서 "스테이션"또는 행 이름 각각을 병합해도 문제가없는 경우입니다. 이 경우 매월 동일한 스테이션 ID/행에 해당하는 별도의 열이됩니다.

setwd("/.../Prism Weather Data All/") 
require(dplyr) 
require(raster) 

#This makes sure only .bil is read (not asc.bil, etc) 

filenames <- dir("/.../Prism Weather Data All/", pattern = "\\.bil$") 

z <- as.data.frame(matrix(NA)) 

#loop through the data, and name each column the name of the date in 
#the spreadsheet (according to Prism's naming convention, the date 
#starts at character 24 and ends at character 29) 

for (file in filenames){ 
    r <- raster(filenames) 
    test <- as.data.frame(r, na.rm=TRUE, row.names=TRUE, col.names=FALSE) 
    names(test)<- c(substring(file, 24, 29)) 
    z <- cbind(z, test) 
} 

#then export the data.frame to CSV!