Cách dễ dàng để xuất nhiều dữ liệu. Khung sang nhiều trang tính Excel


85

Tôi ngạc nhiên khi thấy rằng không có cách nào dễ dàng để xuất nhiều data.frame sang nhiều trang tính của một tệp Excel? Tôi đã thử gói xlsx , có vẻ như nó chỉ có thể ghi vào một trang tính (ghi đè trang tính cũ); Tôi cũng đã thử gói WriteXLS , nhưng nó luôn gây lỗi cho tôi ...

Cấu trúc mã của tôi như thế này: theo thiết kế, đối với mỗi lần lặp, khung dữ liệu đầu ra (tempTable) và sheetName (sn) đã được cập nhật và xuất thành một tab.

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

Tôi có thể xuất sang một số tệp cvs, nhưng phải có một cách dễ dàng để làm điều đó trong Excel, phải không?


3
Bạn đã sai về xlsx . Có một createSheetchức năng, cho phép bạn tạo các trang tính mới, sau đó ghi vào chúng, trong một vòng lặp. Ngoài ra, các chức năng tương đương trong XLConnect được vector hóa, cho phép ghi danh sách các khung dữ liệu vào nhiều trang tính.
joran

@joran, createSheet được sử dụng với addDataFrame chứ không phải write.xlsx? Tôi đã thấy điều đó trước đó trong tài liệu nhưng không thể tìm ra toàn bộ quá trình.
Ogre Magi

Câu trả lời:


144

Bạn có thể ghi vào nhiều trang tính với xlsxgói. Bạn chỉ cần sử dụng một khung khác sheetNamecho mỗi khung dữ liệu và bạn cần thêm 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)

Một tùy chọn khác, cho phép bạn kiểm soát nhiều hơn đối với định dạng và nơi đặt khung dữ liệu, là thực hiện mọi thứ trong mã R / xlsx và sau đó lưu sổ làm việc ở cuối. Ví dụ:

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")

Trong trường hợp bạn có thể thấy nó hữu ích, đây là một số hàm trợ giúp thú vị giúp bạn dễ dàng thêm định dạng, siêu dữ liệu và các tính năng khác vào bảng tính bằng cách sử dụng xlsx: http://www.sthda.com/english/wiki/r2excel-read-write -and-format-easy-excel-files-using-r-software


xlsxkhông quan tâm đến các số ở hàng đầu tiên R đặt ở đó. openxlsxloại bỏ chúng.
buhtz

1
Thêm row.names=FALSEđể xóa tên hàng.
eipi10

@EcologyTom Tôi chuyển từ xlsxđể openxlsxmột thời gian trở lại, như tôi thấy nó trực quan hơn nhiều và nó cũng tránh được sự phụ thuộc java.
eipi10

Có, sự phụ thuộc vào java buộc tôi phải thực hiện chuyển đổi tương tự. Mặc dù mã dài hơn một chút nhưng nó khá đơn giản. Đối với một phương pháp với openxlsxphiên bản 4.0, hãy xem câu trả lời bổ sung của tôi bên dưới.
EcologyTom

2
Có phải chỉ tôi không, hay tờ 2 chỉ đơn giản là ghi đè lên trang 1 khi một người sử dụng mã này?
NewBee

88

Bạn cũng có thể sử dụng thư viện openxlsx để xuất nhiều bộ dữ liệu sang nhiều trang tính trong một sổ làm việc. Ưu điểm của openxlsx so với xlsx là openxlsx loại bỏ các phụ thuộc vào thư viện java.

Viết danh sách data.frame vào các trang tính riêng lẻ bằng cách sử dụng tên danh sách làm tên trang tính.

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

3
Tôi đã sử dụng các gói này và tôi nghĩ openxlsxlà gói nhanh nhất như c ++ của nó. XlConnectsẽ ăn RAM của bạn. Bạn có thể muốn làm một số điểm chuẩn giữa xlsxopenxlsx
Hanjo Jo'burg Odendaal

2
Một ưu điểm khác của gói đó là nó quan tâm đến việc đánh số R ở hàng đầu tiên.
buhtz

4
Cảm ơn, đây openxlsx::write.xlsxlà cách để bắt đầu ... Tôi đã lưu 11 trang tính, mỗi trang tính 20.000x10, hoàn thành trong vài giây trong khi bị xlsx::write.xlsxlỗi sau khi nối trang tính thứ hai vớijava.lang.OutOfMemoryError: Java heap space
Djork

Tôi cần thêm tham số append=TRUEvào write.xlsx để làm cho nó ghi nhiều trang cùng một lúc vào một tệp Excel
mondano

Đáng yêu! Tôi đã tạo danh sách của mình như một phần của vòng lặp và chỉ cần khởi tạo nó ( list_of_dfs <- list()) rồi điền vào nó, bằng cách sử dụng temp_key và temp_df được tạo trong vòng lặp ( list_of_dfs[[temp_key]] = temp_df). Nó cũng rất nhanh bằng văn bản, mặc dù tôi cần 16 trang tính để tạo! Có ai chứng kiến ​​vấn đề với bộ nhớ trong quá trình tạo?
Lionel Trebuchon

30

Có một thư viện mới trong thị trấn, từ rOpenSci: writexl

Khung dữ liệu di động, trọng lượng nhẹ tới trình xuất xlsx dựa trên libxlsxwriter. Không cần Java hoặc Excel

Tôi thấy nó tốt hơn và nhanh hơn các đề xuất ở trên (làm việc với phiên bản dev):

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

1
Cảm ơn! Điều này đã hoạt động ở nơi openxlsx không (tôi không thể cài đặt rtools tại nơi làm việc).
Ape,

Bạn sử dụng phiên bản nào cho việc này? Tải xuống cran mặc định chưa hỗ trợ nhiều trang tính (chưa): 'Lỗi trong writexl :: write_xlsx (list (...: Đối số x phải là khung dữ liệu hoặc danh sách các khung dữ liệu'
JAD

Như tôi đã viết, phiên bản dành cho nhà phát triển.
Giora Simchoni

@JarkoDubbeldam: Tôi đã cài đặt của tôi từ cran và nhiều trang tính làm việc cho tôi (R 3.3.0). Kiểm tra xem các đối tượng bên trong danh sách của bạn có phải là data.frame hay không.
Ape

đây là một trong những thực sự hoạt động. không thể cài đặt xlsx trong r.
Cina

20

Nhiều câu trả lời hay ở đây, nhưng một số trong số đó hơi cũ. Nếu bạn muốn thêm các trang tính khác vào một tệp thì đây là cách tiếp cận mà tôi thấy phù hợp với mình. Để rõ ràng, đây là quy trình làm việc cho openxlsxphiên bản 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")

BIÊN TẬP

Bây giờ tôi đã thử một vài câu trả lời khác và tôi thực sự thích @ Syed. Nó không khai thác tất cả các chức năng openxlsxnhưng nếu bạn muốn một phương pháp xuất nhanh chóng và dễ dàng thì đó có lẽ là phương pháp đơn giản nhất.


8

Tôi không quen thuộc với gói WriteXLS; Tôi thường sử dụng 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)

Điều này chắc chắn có thể được vector hóa, như @joran đã lưu ý ở trên, nhưng chỉ để tạo tên trang tính động một cách nhanh chóng, tôi đã sử dụng for vòng lặp để chứng minh.

Tôi đã sử dụng create=TRUEđối số trong loadWorkbookvì tôi đang tạo tệp .xlsx mới, nhưng nếu tệp của bạn đã tồn tại thì bạn không phải chỉ định điều này, vì giá trị mặc định làFALSE .

Dưới đây là một số ảnh chụp màn hình của sổ làm việc đã tạo:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


1
Tôi chưa sử dụng XLConnect, ví dụ rất chi tiết, cảm ơn!
Ogre Magi

Bạn được chào đón - Tôi thấy nó là một gói rất hữu ích. Có một mô tả khá hay trên CRAN trình bày chi tiết một số tính năng chính, với một ví dụ đẹp trong phần 4 trình bày cách viết các ô R vào một trang tính.
nrussell

5

Trong trường hợp kích thước dữ liệu nhỏ, R có nhiều gói và chức năng có thể được sử dụng theo yêu cầu của bạn.

write.xlsx, write.xlsx2, XLconnect cũng thực hiện công việc nhưng chúng đôi khi chậm so với openxlsx .

Vì vậy, nếu bạn đang xử lý các tập dữ liệu lớn và gặp lỗi java. Tôi muốn đề nghị có một cái nhìn về "openxlsx" thực sự tuyệt vời và giảm thời gian xuống còn .

Tôi đã thử nghiệm tất cả và cuối cùng tôi thực sự ấn tượng với hiệu suất của các khả năng openxlsx.

Dưới đây là các bước để ghi nhiều bộ dữ liệu thành nhiều trang tính.

 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") phải tĩnh vì nó tham chiếu đến một số tiện ích từ Rtools.

Lưu ý: Trong trường hợp Rtools chưa được cài đặt trên hệ thống của bạn, vui lòng cài đặt nó trước để trải nghiệm mượt mà. Đây là liên kết để bạn tham khảo: (chọn phiên bản thích hợp)

https://cran.r-project.org/bin/windows/Rtools/ kiểm tra các tùy chọn theo liên kết bên dưới (cần chọn tất cả hộp kiểm trong khi cài đặt)

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

openxlsxGói thực sự tốt để đọc và ghi dữ liệu khổng lồ từ / trong các tệp excel và có rất nhiều tùy chọn để định dạng tùy chỉnh trong excel.

Thực tế thú vị là chúng ta không phải bận tâm về bộ nhớ heap của java ở đây.


3

Tôi đã gặp vấn đề chính xác này và tôi đã giải quyết nó theo cách này:

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)
}

Bằng cách đó, bạn sẽ không phải tạo một danh sách rất dài theo cách thủ công nếu bạn có hàng tấn khung dữ liệu để ghi vào Excel.


2
Tôi không biết tại sao điều này đang ghi đè trang tính đầu tiên
Lunalo John

1

Tôi thường xuyên sử dụng gói rio để xuất khẩu các loại. Sử dụng rio, bạn có thể nhập danh sách, đặt tên cho từng tab và chỉ định tập dữ liệu. rio biên dịch các gói vào / ra khác và để xuất sang Excel, sử dụng openxlsx.

library(rio)

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

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

0

Cho tôi, WriteXLS cung cấp chức năng bạn đang tìm kiếm. Vì bạn không chỉ định lỗi nào nó trả về, nên tôi chỉ cho bạn một ví dụ:

Thí dụ

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

Giải trình

Nếu x là:

  • danh sách các khung dữ liệu, mỗi khung dữ liệu được ghi vào một trang tính
  • một vectơ ký tự (của R đối tượng), mỗi đối tượng được ghi vào một trang tính
  • điều gì đó khác, sau đó xem trợ giúp nêu rõ:

Thông tin thêm về cách sử dụng

?WriteXLS

trình diễn:

`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.

Giải pháp

Ví dụ của bạn, bạn sẽ cần phải thu thập tất cả data.frame trong một danh sách trong suốt vòng lặp và sử dụng WriteXLSsau khi vòng lặp kết thúc.

Thông tin phiên

  • R 3.2.4
  • WriteXLS 4.0.0

Gói này sẽ làm việc nhưng IMHO tôi sẽ cố gắng tránh sự phụ thuộc của perl (như tôi sẽ cố gắng tránh sự phụ thuộc của Java với xlsx) vì nó làm cho nó khó khăn hơn để thiết lập
R Yoda

0

Tôi thực hiện theo cách này cho openxlsx bằng cách sử dụng hàm sau

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 là chìa khóa vào đây để mở file đang tồn tại
makarand Kulkarni

Ngoài ra nếu bạn muốn viết công thức vào excel thì có một hàm khác có tên là writeFormula, ngoài ra khi bạn viết công thức, tệp cần được làm mới hoặc mở lại sau đó lưu và sau đó đóng trong excel. bản demo được đưa ra ở đây [link ( stackoverflow.com/questions/46914303/... )
makarand Kulkarni

0

Tôi làm việc này mọi lúc, tất cả những gì tôi làm là

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

và tất cả các khung dữ liệu đó đến từ đây

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)
}

rõ ràng là thói quen sapply sẽ tốt hơn ở đây


0

cho một phiên bản thân thiện với lapply ..

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
Bạn có thể thêm một số mô tả cho câu trả lời này để cung cấp ngữ cảnh cho cách trả lời câu hỏi này không?
tshimkus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.