将多个data.frame导出到多个Excel工作表的简便方法


85

我很惊讶地发现没有简单的方法可以将多个data.frame导出到Excel文件的多个工作表中?我试过xlsx包,看来它只能写一张纸(覆盖旧纸);我也尝试了WriteXLS软件包,但是它总是给我错误...

我的代码结构是这样的:根据设计,对于每次迭代,输出数据帧(tempTable)和sheetName(sn)都会更新并导出到一个选项卡中。

for (i in 2 : ncol(code)){ 
        ...
        tempTable <- ...
        sn <- ...
        WriteXLS("tempTable", ExcelFileName = "C:/R_code/../file.xlsx",
              SheetNames = sn);
}

我可以导出到多个cvs文件,但是必须有一种简单的方法可以在Excel中执行此操作,对吗?


3
您对xlsx错了。有一个createSheet功能,允许您循环创建新表,然后将其写入。此外,XLConnect中的等效功能已向量化,从而允许将数据帧列表写入多张纸。
joran 2014年

@ joran,createSheet与addDataFrame一起使用,不是write.xlsx吗?我在文档的较早版本中看到过,但无法弄清楚整个过程。
食人魔魔术师2014年

Answers:


144

您可以使用该xlsx包装写多张纸。您只需要sheetName对每个数据框使用不同的内容,并需要添加append=TRUE

library(xlsx)
write.xlsx(dataframe1, file="filename.xlsx", sheetName="sheet1", row.names=FALSE)
write.xlsx(dataframe2, file="filename.xlsx", sheetName="sheet2", append=TRUE, row.names=FALSE)

另一个选项使您可以更好地控制格式和数据帧的放置位置,它是在R / xlsx代码中进行所有操作,然后最后保存工作簿。例如:

wb = createWorkbook()

sheet = createSheet(wb, "Sheet 1")

addDataFrame(dataframe1, sheet=sheet, startColumn=1, row.names=FALSE)
addDataFrame(dataframe2, sheet=sheet, startColumn=10, row.names=FALSE)

sheet = createSheet(wb, "Sheet 2")

addDataFrame(dataframe3, sheet=sheet, startColumn=1, row.names=FALSE)

saveWorkbook(wb, "My_File.xlsx")

如果您觉得它有用,可以使用一些有趣的帮助程序功能,这些功能使您可以使用以下方法更轻松地向电子表格添加格式,元数据和其他功能xlsxhttp : //www.sthda.com/english/wiki/r2excel-read-write并使用R软件轻松格式化Excel文件


xlsx不关心放在第一行R中的数字。openxlsx删除它们。
buhtz

1
添加row.names=FALSE以删除行名。
eipi10 '16

@EcologyTom我从前切换xlsx到前openxlsx一阵子,因为我发现它更加直观,而且避免了Java依赖。
eipi10

是的,java依赖关系迫使我进行相同的切换。尽管代码要长一点,但是却非常简单。对于openxlsx4.0版本的方法,请参见下面的补充说明。
EcologyTom

2
是我还是第二个人在使用此代码时简单地将第一个人写在第一个人上?
NewBee

88

您还可以使用openxlsx库在单个工作簿中将多个数据集导出到多个工作表。openxlsx优于xlsx的优点是openxlsx消除了对Java库的依赖。

使用列表名称作为工作表名称将data.frames列表写入各个工作表。

require(openxlsx)
list_of_datasets <- list("Name of DataSheet1" = dataframe1, "Name of Datasheet2" = dataframe2)
write.xlsx(list_of_datasets, file = "writeXLSX2.xlsx")

3
我使用了这些软件包,我认为openxlsxC最快。XlConnect会吃掉你的RAM。您可能需要做一些与基准xlsxopenxlsx
Hanjo约堡Odendaal

2
该包的另一个优点是它可以处理第一行中的R编号。
buhtz

4
谢谢,openxlsx::write.xlsx是要走的路...我要保存11张纸,每张纸为20,000x10数据帧,完成后是几秒钟,而xlsx::write.xlsx在第二张纸上附加java.lang.OutOfMemoryError: Java heap space
Djork

我需要将参数添加append=TRUE到write.xlsx,以使其一次将多个工作表写入一个Excel文件
mondano

可爱!我创建了列表作为循环的一部分,只需要list_of_dfs <- list()使用在循环(list_of_dfs[[temp_key]] = temp_df)中构造的temp_key和temp_df对其进行初始化(),然后进行填充。尽管我需要创建16张纸,但是书写速度还是非常快!在创建过程中,有没有人看到内存问题?
Lionel Trebuchon

30

rOpenSci镇上有一个新图书馆:writexl

基于libxlsxwriter的可移植,轻量级数据帧到xlsx导出器。无需Java或Excel

我发现它比上面的建议(使用开发版本)更好,更快。

library(writexl)
sheets <- list("sheet1Name" = sheet1, "sheet2Name" = sheet2) #assume sheet1 and sheet2 are data frames
write_xlsx(sheets, "path/to/location")

1
谢谢!这在openxlsx不起作用的地方起作用(我无法在工作中安装rtools)。
Ape

您使用哪个版本?默认的cran下载不支持多张工作表(尚未):'writexl :: write_xlsx(list(...:参数x必须是数据帧或数据帧列表)中的错误'
JAD

如我所写,开发版本。
Giora Simchoni

@JarkoDubbeldam:我从cran安装了我的矿井,多张工作表对我有用(R 3.3.0)。检查列表内的对象是否为data.frames。
Ape

这是一个真正的作品。无法在R中安装xlsx。
Cina

20

这里有很多不错的答案,但其中有些却有些过时。如果您想将更多工作表添加到单个文件中,那么这就是我发现的适用于我的方法。为了清楚起见,这是openxlsx版本4.0的工作流程

# Create a blank workbook
OUT <- createWorkbook()

# Add some sheets to the workbook
addWorksheet(OUT, "Sheet 1 Name")
addWorksheet(OUT, "Sheet 2 Name")

# Write the data to the sheets
writeData(OUT, sheet = "Sheet 1 Name", x = dataframe1)
writeData(OUT, sheet = "Sheet 2 Name", x = dataframe2)

# Export the file
saveWorkbook(OUT, "My output file.xlsx")

编辑

我现在已经尝试了其他一些答案,实际上我真的很喜欢@Syed。它不能利用的所有功能,openxlsx但是如果您想要一种快速简便的导出方法,那可能是最简单的方法。


8

我对包装不熟悉WriteXLS; 我通常使用XLConnect

library(XLConnect)
##
newWB <- loadWorkbook(
  filename="F:/TempDir/tempwb.xlsx",
  create=TRUE)
##
for(i in 1:10){
  wsName <- paste0("newsheet",i)
  createSheet(
    newWB,
    name=wsName)
  ##
  writeWorksheet(
    newWB,
    data=data.frame(
      X=1:10,
      Dataframe=paste0("DF ",i)),
    sheet=wsName,
    header=TRUE,
    rownames=NULL)
}
saveWorkbook(newWB)

正如上面@joran所指出的,这当然可以向量化,但是为了快速生成动态工作表名称,我使用了一个for循环来演示。

自创建新的.xlsx文件以来,我一直create=TRUE在使用参数loadWorkbook,但是如果您的文件已经存在,则无需指定它,因为默认值为FALSE

以下是创建的工作簿的一些屏幕截图:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明


1
我没有使用XLConnect,非常详细的示例,谢谢!
Ogre Magi 2014年

不用客气-我发现它是一个非常有用的软件包。CRAN上有一个很好的小插图,详细介绍了一些主要功能,第4节中的一个漂亮示例演示了如何将R绘图写入工作表。
nrussell 2014年

5

如果数据量很小,则R具有许多可根据您的要求使用的软件包和功能。

write.xlsx,write.xlsx2,XLconnect也可以完成工作,但是与openxlsx相比,这些有时速度较慢

因此,如果您处理的是大型数据集,并且遇到了Java错误。我建议看看“ openxlsx”,它真的很棒,可以将时间减少到。

我已经进行了全部测试,最终我对openxlsx功能的性能印象深刻。

以下是将多个数据集写入多个工作表的步骤。

 install.packages("openxlsx")
 library("openxlsx")

    start.time <- Sys.time()

    # Creating large data frame
    x <- as.data.frame(matrix(1:4000000,200000,20))
    y <- as.data.frame(matrix(1:4000000,200000,20))
    z <- as.data.frame(matrix(1:4000000,200000,20))

    # Creating a workbook
    wb <- createWorkbook("Example.xlsx")
    Sys.setenv("R_ZIPCMD" = "C:/Rtools/bin/zip.exe") ## path to zip.exe

Sys.setenv(“ R_ZIPCMD” =“ C:/Rtools/bin/zip.exe”)必须是静态的,因为它引用了Rtools的某些实用程序。

注意:如果您的系统上未安装Rtools,请先安装Rtools以获得流畅的体验。这是供您参考的链接:(选择适当的版本)

https://cran.r-project.org/bin/windows/Rtools/ 根据下面的链接检查选项(安装时需要选中所有复选框)

https://cloud.githubusercontent.com/assets/7400673/12230758/99fb2202-b8a6-11e5-82e6-836159440831.png

    # Adding a worksheets : parameters for addWorksheet are 1. Workbook Name 2. Sheet Name

    addWorksheet(wb, "Sheet 1")
    addWorksheet(wb, "Sheet 2")
    addWorksheet(wb, "Sheet 3")

    # Writing data in to respetive sheets: parameters for writeData are 1. Workbook Name 2. Sheet index/ sheet name 3. dataframe name

    writeData(wb, 1, x)

    # incase you would like to write sheet with filter available for ease of access you can pass the parameter withFilter = TRUE in writeData function.
    writeData(wb, 2, x = y, withFilter = TRUE)

    ## Similarly writeDataTable is another way for representing your data with table formatting:

    writeDataTable(wb, 3, z)

    saveWorkbook(wb, file = "Example.xlsx", overwrite = TRUE)

    end.time <- Sys.time()
    time.taken <- end.time - start.time
    time.taken

openxlsx软件包非常适合从excel文件中读取/写入大量数据,并且在excel中具有许多用于自定义格式的选项。

有趣的事实是,我们在这里不必担心Java堆内存。


3

我遇到了这个确切的问题,并以此方式解决了这个问题:

library(openxlsx) # loads library and doesn't require Java installed

your_df_list <- c("df1", "df2", ..., "dfn")

for(name in your_df_list){
  write.xlsx(x = get(name), 
             file = "your_spreadsheet_name.xlsx", 
             sheetName = name)
}

这样,如果您有大量数据帧要写入Excel,则无需手动创建一个很长的列表。


2
我不知道为什么这会覆盖第一个工作表
Lunalo John

1

我经常将打包的rio用于各种出口。使用rio,您可以输入一个列表,命名每个选项卡并指定数据集。rio编译其他输入/输出程序包,并导出到Excel,使用openxlsx。

library(rio)

filename <- "C:/R_code/../file.xlsx"

export(list(sn1 = tempTable1, sn2 = tempTable2, sn3 = tempTable3), filename)

0

对我来说,WriteXLS提供您正在寻找的功能。由于您没有指定返回的错误,因此我举一个例子:

library(WriteXLS)
x <- list(sheet_a = data.frame(a=letters), sheet_b = data.frame(b = LETTERS))
WriteXLS(x, "test.xlsx", names(x))

说明

如果x是:

  • 数据帧列表,每个数据帧都写到一张纸上
  • (R个对象的)一个字符向量,每个对象都写到一张纸上
  • 其他内容,然后查看帮助内容:

更多用法

?WriteXLS

显示:

`x`: A character vector or factor containing the names of one or
     more R data frames; A character vector or factor containing
     the name of a single list which contains one or more R data
     frames; a single list object of one or more data frames; a
     single data frame object.

对于您的示例,您需要在循环期间收集列表中的所有data.frames,并WriteXLS在循环完成后使用。

会话信息

  • R 3.2.4
  • 写XLS 4.0.0

该软件包可以工作,但是恕我直言,我会尝试避免对perl的依赖(因为我会尽量避免对Java的依赖xlsx),因为它会使设置更加困难
R Yoda

0

我使用以下功能对openxlsx这样做

mywritexlsx<-function(fname="temp.xlsx",sheetname="Sheet1",data,
                  startCol = 1, startRow = 1, colNames = TRUE, rowNames = FALSE)
{
  if(! file.exists(fname))
    wb = createWorkbook()
  else
   wb <- loadWorkbook(file =fname)
  sheet = addWorksheet(wb, sheetname)

  writeData(wb,sheet,data,startCol = startCol, startRow = startRow, 
          colNames = colNames, rowNames = rowNames)
  saveWorkbook(wb, fname,overwrite = TRUE)
}

loadWorkbook是打开现有文件的关键
makarand kulkarni

另外,如果要向excel编写公式,则还有一个名为writeFormula的函数,此外,一旦编写公式,就需要刷新或重新打开文件,然后保存并在excel中关闭。演示在这里给出[link(stackoverflow.com/questions/46914303/…
makarand kulkarni

0

我一直这样做,我要做的就是

WriteXLS::WriteXLS(
    all.dataframes,
    ExcelFileName = xl.filename,
    AdjWidth = T,
    AutoFilter = T,
    FreezeRow = 1,
    FreezeCol = 2,
    BoldHeaderRow = T,
    verbose = F,
    na = '0'
  )

所有这些数据帧都来自这里

all.dataframes <- vector()
for (obj.iter in all.objects) {
  obj.name <- obj.iter
  obj.iter <- get(obj.iter)
  if (class(obj.iter) == 'data.frame') {
      all.dataframes <- c(all.dataframes, obj.name)
}

显然,套用例行程序在这里会更好


0

适用于友善的版本

library(data.table)
library(xlsx)

path2txtlist <- your.list.of.txt.files
wb <- createWorkbook()
lapply(seq_along(path2txtlist), function (j) {
sheet <- createSheet(wb, paste("sheetname", j))
addDataFrame(fread(path2txtlist[j]), sheet=sheet, startColumn=1, row.names=FALSE)
})

saveWorkbook(wb, "My_File.xlsx")

1
您能否在此答案中添加一些说明,以提供有关此答案的方式的上下文?
tshimkus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.