Простий спосіб експортувати кілька 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);
}

Я можу експортувати до декількох файлів резюме, але це повинен бути простий спосіб зробити це в Excel, так?


3
Ви помиляєтесь щодо xlsx . Існує createSheetфункція, яка дозволяє створювати нові аркуші, а потім писати на них у циклі. Крім того, еквівалентні функції в XLConnect векторизуються, що дозволяє писати список кадрів даних на декілька аркушів.
joran

@joran, createSheet використовується з addDataFrame, а не write.xlsx? Я бачив це раніше в документі, але не міг зрозуміти весь процес.
Ogre Magi

Відповіді:


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

Якщо вам це може виявитися корисним, ось кілька цікавих допоміжних функцій, які спрощують додавання форматування, метаданих та інших функцій до електронних таблиць за допомогою 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 див. Мою додаткову відповідь нижче.
Екологія, Том,

2
Це лише я, чи аркуш 2 просто пише над аркушем 1, коли використовується цей код?
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
Я використовував ці пакети, і я думаю, що 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 аркушів, які мені потрібно було створити! Хтось був свідком проблем із пам’яттю під час створення?
Лайонел

30

У місті є нова бібліотека від rOpenSci: writexl

Портативний, легкий фрейм даних для експортера xlsx на основі libxlsxwriter. Не потрібно 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 на роботі).
Мавпа

Яку версію ви використовуєте для цього? Завантажений кран за замовчуванням не підтримує декілька аркушів (поки): 'Помилка в writexl :: write_xlsx (list (...: Argument x must be a data frame or list of data data)
JAD

Як я вже писав, версія розробника.
Джора Сімчоні

@JarkoDubbeldam: Я встановив свій з cran, і кілька аркушів працюють для мене (R 3.3.0). Перевірте, чи об’єктами у вашому списку є data.frames.
Мавпа

це справді працює. не вдалося встановити xlsx в r.
Кіна

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's. Він не використовує всю функціональність, 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 .

Отже, якщо ви маєте справу з великими наборами даних і натрапили на помилки Java. Я б запропонував поглянути на "openxlsx", який дійсно приголомшливий, і скоротити час до 1/12 .

Я все перевірив і, нарешті, я був справді вражений продуктивністю можливостей 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 тут.


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
Не знаю, чому це перезаписує перший аркуш
Лунало Джон,

1

Я регулярно використовую упакований ріо для експорту всіх видів. Використовуючи 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
  • WriteXLS 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 Кулкарни

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.