วิธีง่ายๆในการส่งออก data.frame หลายแผ่นไปยังแผ่นงาน Excel หลายแผ่น


88

ฉันประหลาดใจที่พบว่าไม่มีวิธีง่ายๆในการส่งออก 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, createSheet ใช้กับ addDataFrame not write.xlsx? ฉันเห็นสิ่งนั้นก่อนหน้านี้ในเอกสาร แต่ไม่สามารถเข้าใจกระบวนการทั้งหมดได้
Ogre Magi

คำตอบ:


149

คุณสามารถเขียนลงในแผ่นงานหลายแผ่นด้วย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")

ในกรณีที่คุณอาจพบว่ามีประโยชน์ต่อไปนี้เป็นฟังก์ชันตัวช่วยที่น่าสนใจซึ่งช่วยให้เพิ่มการจัดรูปแบบข้อมูลเมตาและคุณสมบัติอื่น ๆ ให้กับสเปรดชีตได้ง่ายขึ้นโดยใช้xlsx: http://www.sthda.com/english/wiki/r2excel-read-write - และฟอร์แมตได้อย่างง่ายดาย excel ไฟล์โดยใช้ซอฟต์แวร์ r


xlsxไม่ดูแลตัวเลขในแถวแรก R ที่วางไว้ที่นั่น openxlsxลบออก
buhtz บอกว่ารับการฉีดวัคซีน

1
เพิ่มrow.names=FALSEเพื่อลบชื่อแถว
eipi10

@EcologyTom ฉันเปลี่ยนจากxlsxไปopenxlsxสักพักแล้วเพราะฉันพบว่ามันใช้งานง่ายกว่ามากและยังหลีกเลี่ยงการพึ่งพา java
eipi10

ใช่การพึ่งพา java บังคับให้ฉันต้องเปลี่ยนเหมือนกัน แม้ว่ารหัสจะยาวกว่าเล็กน้อย แต่ก็ค่อนข้างตรงไปตรงมา สำหรับวิธีการกับopenxlsxเวอร์ชัน 4.0 โปรดดูคำตอบเพิ่มเติมด้านล่าง
EcologyTom

6
เป็นแค่ฉันเองหรือแผ่นงาน 2 เขียนทับแผ่นงาน 1 เมื่อมีคนใช้รหัสนี้
NewBee

94

คุณยังสามารถใช้ไลบรารี 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
ฉันใช้แพ็คเกจเหล่านี้แล้วและคิดว่าopenxlsxเร็วที่สุดเท่า c ++ XlConnectจะกินแรมของคุณ คุณอาจต้องการเปรียบเทียบระหว่างxlsxและopenxlsx
Hanjo Jo'burg 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()) จากนั้นกรอกข้อมูลโดยใช้ temp_key และ temp_df ที่สร้างขึ้นระหว่างลูป ( list_of_dfs[[temp_key]] = temp_df) นอกจากนี้ยังเขียนได้รวดเร็วมากแม้ว่าฉันจะต้องสร้าง 16 แผ่นก็ตาม! มีใครเห็นปัญหาเกี่ยวกับความทรงจำระหว่างการสร้างหรือไม่?
Lionel Trebuchon

32

มีห้องสมุดใหม่ในเมืองจาก rOpenSci: writexl

กรอบข้อมูลแบบพกพาน้ำหนักเบาไปยังผู้ส่งออก xlsx ตาม libxlsxwriter ไม่จำเป็นต้องใช้ Java หรือ Excel

ฉันพบว่ามันดีกว่าและเร็วกว่าคำแนะนำข้างต้น (ทำงานกับเวอร์ชัน dev):

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 เริ่มต้นไม่รองรับแผ่นงานหลายแผ่น (ยัง): 'Error in writexl :: write_xlsx (list (... : Argument x must be a data frame or list of data frames'
JAD

อย่างที่ฉันเขียนเวอร์ชัน dev
Giora Simchoni

@JarkoDubbeldam: ฉันติดตั้งของฉันจาก cran และหลายแผ่นทำงานให้ฉัน (R 3.3.0) ตรวจสอบว่าวัตถุภายในรายการของคุณเป็น data.frames หรือไม่
Ape

นี่เป็นวิธีที่ใช้งานได้จริง ไม่สามารถติดตั้ง xlsx ใน r
Cina

22

คำตอบที่ดีมากมายที่นี่ แต่บางคำก็ดูล้าสมัย หากคุณต้องการเพิ่มเวิร์กชีตเพิ่มเติมลงในไฟล์เดียวนี่คือแนวทางที่ฉันคิดว่าเหมาะกับฉัน เพื่อความชัดเจนนี่คือเวิร์กโฟลว์สำหรับ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วนซ้ำเพื่อสาธิต

ผมใช้create=TRUEอาร์กิวเมนต์ในloadWorkbookตั้งแต่ผมสร้างไฟล์ .xlsx ใหม่ FALSEแต่ถ้าไฟล์ของคุณอยู่แล้วแล้วคุณไม่ต้องระบุนี้เป็นค่าเริ่มต้นคือ

นี่คือภาพหน้าจอบางส่วนของสมุดงานที่สร้างขึ้น:

ใส่คำอธิบายภาพที่นี่

ใส่คำอธิบายภาพที่นี่

ใส่คำอธิบายภาพที่นี่


1
ฉันไม่ได้ใช้ XLConnect ตัวอย่างที่ละเอียดมากขอบคุณ!
Ogre Magi

ไม่เป็นไร - ฉันพบว่ามันเป็นแพ็คเกจที่มีประโยชน์มาก มีบทความสั้น ๆที่ดีเกี่ยวกับ CRANซึ่งให้รายละเอียดคุณสมบัติหลักบางประการโดยมีตัวอย่างที่ดีในส่วนที่ 4 ที่สาธิตวิธีการเขียนพล็อต R ลงในแผ่นงาน
nrussell

5

ขนาดข้อมูลในกรณีเล็ก R มีแพ็คเกจและฟังก์ชั่นมากมายที่สามารถใช้งานได้ตามความต้องการของคุณ

write.xlsx, write.xlsx2, XLconnectก็ทำงานได้เช่นกัน แต่บางครั้งก็ช้าเมื่อเทียบกับopenxlsx 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

หมายเหตุ: Incase 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 heap ที่นี่


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


3
ฉันไม่รู้ว่าทำไมจึงเขียนทับแผ่นงานแรก
Lunalo John

สิ่งนี้จะเขียนทับแผ่นงานฉันและคนอื่น ๆ ก็ประสบปัญหาเช่นกัน ดูที่นี่ - stackoverflow.com/questions/57278418/…
Skurup

2

ฉันใช้ริโอแบบบรรจุหีบห่อเพื่อการส่งออกทุกชนิดเป็นประจำ เมื่อใช้ 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หลังจากการวนซ้ำเสร็จสิ้น

ข้อมูลเซสชัน

  • ร 3.2.4
  • เขียน XLS 4.0.0

แพ็คเกจนี้จะใช้งานได้ แต่ IMHO ฉันจะพยายามหลีกเลี่ยงการพึ่งพา 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 ดูตัวอย่างได้ที่นี่ [ลิงค์ ( 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)
}

เห็นได้ชัดว่ากิจวัตรของ sapply จะดีกว่าที่นี่


0

สำหรับรุ่น lapply-friendly ..

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.