将函数应用于R中不同工作簿中的不同工作表

时间:2013-07-24 12:24:06

标签: r for-loop xlconnect

我是R的新手,我目前正在尝试使用XLConnect包将函数应用于不同工作簿中相同索引的工作表。

到目前为止,我已经设法读取了excel文件的文件夹:

filenames <- list.files( "file path here", pattern="\\.xls$", full.names=TRUE)

我循环浏览不同的文件,阅读每个文件的每个工作表

for (i in 1:length(filenames)){
    tmp<-loadWorkbook(file.path(filenames[i],sep=""))
    lst<- readWorksheet(tmp, 
            sheet = getSheets(tmp), startRow=5, startCol=1, header=TRUE)}

我想我想做的是循环文件名中的文件,然后使用相同索引的工作表(例如,所有文件的第一个工作表,然后是所有文件的第二个工作表等)并将这些保存到新工作簿(包含所有第一个工作表的第一个工作簿,然后是包含所有第二个工作表的第二个工作簿等),每个原始工作表的新工作表取自先前的文件,然后使用

for (sheet in newlst){
    Count<-t(table(sheet$County))}

并将我的函数应用于参数Count。

有谁知道我该怎么做或者根本不给我任何指导?对不起,如果不清楚,请询问,我会尝试进一步解释!谢谢:))

2 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,以下内容可以解决您的问题:

require(XLConnect)

# Example: workbooks w1.xls - w[n].xls each with sheets S1 - S[m]
filenames = list.files("file path here", pattern = "\\.xls$", full.names = TRUE)

# Read data from all workbooks and all worksheets
data = lapply(filenames, function(f) {
  wb = loadWorkbook(f)
  readWorksheet(wb, sheet = getSheets(wb)) # read all sheets in one go
})

# Assumption for this example: all workbooks contain same number of sheets
nWb = sapply(data, length)
stopifnot(diff(range(nWb)) == 0)
nWb = min(nWb)

for(i in seq(length.out = nWb)) {
  # List of data.frames of all i'th sheets
  dout = lapply(data, "[[", i)
  # Note: write all collected sheets in one go ...
  writeWorksheetToFile(file = paste0("wout", i, ".xls"), data = dout, 
                       sheet = paste0("Sout", seq(length.out = length(data))))
}

答案 1 :(得分:0)

使用gdata / xlsx可能是最好的。虽然它是最慢的,但它是更直观的一种。

如果excel的排序方式不同,此方法将失败。

鉴于没有真实的例子,这里有一些值得思考的东西。 Gdata需要安装perl。

library(gdata)
filenames <- list.files( "file path here", pattern="\\.xls$", full.names=TRUE)
amountOfSheets <- #imput something

#This snippet gets the first sheet out of all the files and combining them
readXlsSheet <- function(whichSheet, files){
 for(i in seq(files)){
    piece <- read.xls(files[i], sheet=whichSheet)
    #rbinding frames should work if the sheets are similar, use merge if not.
    if(i == 1) complete <- piece else complete <- rbind(complete, piece)
  }
  complete
}
#Now looping through all the sheets using the previous method
animals <- lapply(seq(amountOfSheets), readXlsSheet, files=filenames)
#The output is a list where animals[[n]] has the all the nth sheets combined.          

xlsx可能只能在32位R上运行,并且有自己公平的问题。

library(xlsx)
filenames <- list.files(pattern="\\.xls$", full.names=TRUE)
amountOfSheets <-  2#imput something

#This snippet gets the first sheet out of all the files and combining them
 readXlsSheet <- function(whichSheet, files){
    for(i in seq(files)){
      piece <- read.xlsx(files[i], sheetIndex=whichSheet)
      #rbinding frames should work if the sheets are similar, use merge if not.
      if(i == 1) complete <- piece else complete <- rbind(complete, piece)
    }
  complete
}
readXlsSheet(1, filenames)
#Now looping through all the sheets using the previous method
animals <- lapply(seq(amountOfSheets), readXlsSheet, files=filenames)