2017-02-22 1 views
0

에 dataframe에 병합 :여러 XLSX 파일을 읽고 내가 코드를 쓰고 있어요 R

  • 폴더

  • 종류의 목록을 읽고 목록에서 특정 텍스트 요소와 폴더를 추출

  • 각 파일

    내부 탭/시트를 찾아 각 폴더

  • 에서 전체 파일 이름을 가져

  • 루프/lapply read.xlsx() 파일

궁극적 인 목표 모든 탭을 읽는 것입니다 내 중첩 된 목록 이상/각 폴더에서 해당 파일의 시트에 열을 만드는 동안 사용자가 어떤 탭/시트인지, 어떤 폴더에서 왔는지 확인한 다음 한 번에 모든 항목을 병합합니다.

엑셀 파일을 읽을 때 선호하는 패키지는 'openxlsx'입니다.

여기 폴더와 파일을 얻기를위한 내 코드입니다 : 내가 루프 수 없었다

path<- "/Users/jackserna/Google Drive/Folder" 
dataFolders<- list.files(path) 
dataFolders<- sort(dataFolders[starts_with(match = "FY", vars = dataFolders)]) 
files<- lapply(lapply(dataFolders, FUN = function(x){ 
    paste(path,x,sep = "/") 
    }), FUN = function(x){ 
      list.files(x, pattern = "*.xlsx", full.names = TRUE) 
}) 

/내 모든 파일과 내 모든 시트에 대한 읽기 기능을 적용 할 수 있습니다. 나는 하나 이상의 폴더를 읽지 않을 것이고, 이것은 반복되어야 할 것이다. 내가

data.to.merge <- lapply(lapply(files[[1]], FUN = function(x){ 
    read.xlsx(x, sheet = 3, cols = 1:5) 
}), na.omit) 
merged.daata <- Reduce(function(...) merge(..., all = T), data.to.merge) 

그러나,이 방법은 제가 읽어 각 시트에 대한 별도의 컬럼으로 시트 이름을 추가하는 것을 허용하지 않습니다 ... this post에서 일부 코드를 사용했다.이 방법은 시트 # 3의 데이터가 있다고 가정합니다 ,하지만이 파일들에 대한 나의 당황 스러움에 대해서는 그렇지 않습니다. 데이터는 여러 시트에 분산되어 있으며 일부 시트는 병합을 위해 무시해야합니다. 모든 시트를 잡고 내가 원하지 않는 시트를 구문 분석하기위한 시도에서

, 여기에 행해졌 내용은 다음과 같습니다

allsheets<- list() 
for(i in files){ 
    for(j in i){ 
    sheets<- getSheetNames(j) 
    allsheets<- cbind(allsheets,sheets) 
    } 
} 

그러나 이것은 읽기 사용할 수 있도록 악몽으로 설정하고있다 병합.

내가 얻으려고하는 것을 R에게 어떻게 이해시킬 수 있습니까?

답변

0

나는 당신의 별개의 기능들에 대해 이산적일 것이므로 어떤 일이 잘못되고 또한 R을 메모리 집약적 인 엑셀 패키지 후에 정리할 수있는 기회를 줄 수 있습니다. 모든 것을 하나의 명령으로 푸시하면 늪에 빠져서 추락 할 것입니다. 당신이 메모리에 sheet_list이 좋아하는 패키지를 사용하여 읽을되면

이 그것을 수행해야합니다

for (i in sheet_list({ 
new_sheet<- your_read_command(sheet_list[i]) 
    #subsitute using whatever reader package command you use likexlConnect or xlsx 
new_sheet$sheetname<- i #(adding the column with sheet name prior to binding) 
data<-rbind(data, new_sheet) 
rm(new_sheet) 
gc()}` 

rm() & gc() 여기에 대규모 중요하다. 모든 Excel 판독기는 JARS 기반이며 HOG 메모리가 시스템을 손상시키는 것을 알 수 있습니다. 데이터가 바인딩 된 후 각 개체를 제거한 다음 가비지 수집을 중단하여 정지 또는 평면 충돌을 방지하십시오.

나는 CSV로 부품을 테스트했으며 작동합니다 ... 지금 Excel 패키지를 사용하고 비트를 약간 조정해야합니다. 의견을 게시하는 데 도움이 필요하면 ...

OH 및 ... 루프를 시작하기 전에 data < -data.frame()`을 (를) 만들고 모든 열 이름을 지정하십시오. 묶어 둘 무언가를 루프하십시오!

+0

나는이 루프를 시험해보고있다 :'data <- setNames (data.frame (matrix ncol = 207, nrow = 0)), column_names) wksheets <- list.files (recursive = T, pattern = ' * .XLSX ')에 대한 (I wksheets에서) { new_file <- loadWorkbook (wksheets [I]) sheetnames <- sheetnames - getSheets (new_file) sheetnames <: (j에 대한 [3 길이 (sheetnames)] sheetnames) { sheet_list <- readWorkbook (sheetnames [J], startRow = 2 COLNAMES = FALSE) sheet_list $ Reading.Center <- J} 데이터 <- rbind (데이터 sheet_list) RM (sheet_list) RM (시트 넘버) gc() }'하지만 모호한 오류가 발생했습니다. 오류 : NullPointerException (Java) : –

+0

이 해결책을 따르십시오. http : //stackoverflow.com/questions/15825004/xlconnect-loadworkbook-error-poixmlexception-java – sconfluentus

0

나는 readxl 패키지를 추가로 권장 할 수 있습니다. 그것은 아마도 워크 시트 안의 시트 수를 감지 할 수 없지만, XLConnect로 시트를 찾은 후에 사용할 수 있습니다. 위해

library(data.table) 
my.monthly.excel.files <- "../../../../../../Documents/Output/Monthly/" 
my.file.list <- data.table(File.Name = list.files(path = my.monthly.excel.files , pattern = ".xlsx$" , recursive = FALSE, include.dirs = FALSE)) 
rbindlist(lapply(my.file.list[,File.Name], function(file){print(file); read_excel(path = paste0(my.monthly.excel.files, file), sheet = "sheet_name")})) 

내가 각 열 중 하나 인 텍스트, 숫자 또는 날짜로 가져올에 대한 열 유형을 정의 경고를 제거합니다.

+0

openconnects, XLconnect , readxl과 같이 사용되지만 deprecated 함수에서는 불만을 갖습니다. XLconnect가 더 일관되게 작동하는 것 같습니다. 모든 사람들의 정보를 위해 저는 R 버전 3.3.2, openxlsx 버전 4.0.0, XLconnect 버전 0.2-12 및 readxl 버전 0.1.1을 사용하고 있습니다. 실행중인 버전을 지정하지 않으면 data.table 또는 rbindlist와 같이 사용되지 않는 기능을 사용하지 마십시오. 나는 당신이 tbl_df()를 의미하는 줄 알았지 만, "my.file.list [, File.Name]"문법으로는 의미가 있지만 말이 맞지 않습니다. 'Error : corrupt data frame' –

+0

두 개의 명령'data.table'과'rbindlist'는 data.table 패키지의 일부입니다. 그들이 더 이상 사용되지 않으므로 지금 전화를 추가했습니다. – hannes101

1

나는이 특정 데이터를 해결할 수 없었지만, 내년을 대비하여 파일 구조를 약간 변경했습니다. data.table 패키지가 중첩 목록을 데이터 프레임과 같은 것으로 가져 오는 데 정말 유용하다는 것을 알았습니다.

아래의 모든 데이터는 지정된 시트 이름 (또는 번호)에서만 읽습니다.

### Get list of folder names 
dataFolders<- list.files(path = path) 
dataFolders<- sort(dataFolders[starts_with(match = "FY", vars = dataFolders)]) 

### Get list of files for each regional folder 
files<- lapply(lapply(dataFolders, FUN = function(x){ 
    paste(path,x,sep = "/")}), FUN = function(x){ 
      list.files(x, pattern = "*.xlsx", full.names = TRUE) 
}) 

dataPrep<- lapply(files, FUN = function(x){ 
    lapply(lapply(x, FUN = function(x){ 
      read.xlsx(x, sheet = "Sheet Name", cols = 1:6)}), na.omit) 
}) 
transform<- rbindlist(lapply(dataPrep, FUN = function(x){ 
    rbindlist(x, use.names = TRUE) 
}), use.names = TRUE) 

에는 악몽 솔루션이 없습니다, 그러나 데이터 항목의 표준해야한다.

관련 문제