Uma maneira fácil de exportar vários data.frame para várias planilhas do Excel

88

Estou surpreso ao descobrir que não existe uma maneira fácil de exportar vários data.frame para várias planilhas de um arquivo Excel. Tentei o pacote xlsx , parece que ele só pode gravar em uma folha (substituir a folha antiga); Eu também tentei o pacote WriteXLS , mas ele me dá erros o tempo todo ...

Minha estrutura de código é assim: por design, para cada iteração, o dataframe de saída (tempTable) e o sheetName (sn) foram atualizados e exportados em uma guia.

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

Posso exportar para vários arquivos cvs, mas tem que haver uma maneira fácil de fazer isso no Excel, certo?

Ogre Magi
fonte
3
Você está errado sobre xlsx . Existe uma createSheetfunção que permite criar novas planilhas e, em seguida, escrever nelas em um loop. Além disso, as funções equivalentes em XLConnect são vetorizadas, permitindo a gravação de uma lista de quadros de dados em várias planilhas.
joran
@joran, createSheet é usado com addDataFrame não write.xlsx? Eu vi isso no início do documento, mas não consegui entender todo o processo.
Ogre Magi

Respostas:

149

Você pode escrever em várias folhas com o xlsxpacote. Você só precisa usar um diferente sheetNamepara cada quadro de dados e adicionar 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)

Outra opção, que fornece mais controle sobre a formatação e onde o quadro de dados é colocado, é fazer tudo dentro do código R / xlsx e salvar a pasta de trabalho no final. Por exemplo:

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

Caso você possa achar útil, aqui estão algumas funções auxiliares interessantes que tornam mais fácil adicionar formatação, metadados e outros recursos a planilhas usando xlsx: http://www.sthda.com/english/wiki/r2excel-read-write -e-formatar-facilmente-arquivos-excel-usando-r-software

eipi10
fonte
xlsxnão cuida dos números na primeira linha R colocando lá. openxlsxRemova eles.
buhtz
1
Adicionar row.names=FALSEpara remover nomes de linhas.
eipi10
@EcologyTom Mudei de xlsxpara openxlsxum tempo atrás, pois acho muito mais intuitivo e também evita a dependência de java.
eipi10
Sim, a dependência de java me forçou a fazer a mesma troca. Embora o código seja um pouco mais longo, é bastante direto. Para um método com a openxlsxversão 4.0, veja minha resposta complementar abaixo.
EcologyTom
6
Sou só eu ou a folha 2 simplesmente escreve sobre a folha 1 quando se usa esse código?
NewBee de
94

Você também pode usar a biblioteca openxlsx para exportar vários conjuntos de dados para várias planilhas em uma única pasta de trabalho. A vantagem do openxlsx sobre o xlsx é que o openxlsx remove as dependências das bibliotecas java.

Escreva uma lista de data.frames em planilhas individuais usando nomes de lista como nomes de planilha.

require(openxlsx)
list_of_datasets <- list("Name of DataSheet1" = dataframe1, "Name of Datasheet2" = dataframe2)
write.xlsx(list_of_datasets, file = "writeXLSX2.xlsx")
Syed
fonte
3
Eu usei esses pacotes e acho que openxlsxé o mais rápido que o c ++. XlConnectvai comer sua RAM. Você pode querer fazer algum benchmarking entre xlsxeopenxlsx
Hanjo Jo'burg Odendaal
2
Outra vantagem desse pacote é que ele cuida da numeração R na primeira linha.
buhtz
4
Obrigado, openxlsx::write.xlsxé o caminho a seguir ... Eu estava salvando 11 planilhas, cada uma com dataframe de 20.000 x 10, feito em alguns segundos xlsx::write.xlsxcom java.lang.OutOfMemoryError: Java heap space
erro
Eu precisava adicionar o parâmetro append=TRUEpara write.xlsx para fazê-lo escrever várias planilhas de uma vez em um arquivo Excel
mondano
Adorável! Eu criei minha lista como parte de um loop, e apenas tive que inicializá-la ( list_of_dfs <- list()) e então preenchê-la, usando temp_key e temp_df construídos durante o loop ( list_of_dfs[[temp_key]] = temp_df). Também foi muito rápido na escrita, apesar das 16 folhas que precisei criar! Alguém testemunhou problemas de memória durante a criação?
Lionel Trebuchon
32

Há uma nova biblioteca na cidade, da rOpenSci: writexl

Frame de dados portátil e leve para exportador xlsx baseado em libxlsxwriter. Não requer Java ou Excel

Achei melhor e mais rápido do que as sugestões acima (trabalhando com a versão dev):

library(writexl)
sheets <- list("sheet1Name" = sheet1, "sheet2Name" = sheet2) #assume sheet1 and sheet2 are data frames
write_xlsx(sheets, "path/to/location")
Giora Simchoni
fonte
1
Obrigado! Isso funcionou onde o openxlsx não funcionou (não consigo instalar o rtools no trabalho).
Macaco
Qual versão você usa para isso? O download cran padrão não oferece suporte a várias planilhas (ainda): 'Erro em writexl :: write_xlsx (list (...: O argumento x deve ser um quadro de dados ou uma lista de quadros de dados'
JAD
Como escrevi, a versão dev.
Giora Simchoni
@JarkoDubbeldam: Instalei o meu a partir do cran e várias folhas funcionam para mim (R 3.3.0). Verifique se os objetos dentro da sua lista são data.frames.
Ape
este é um realmente funciona. não foi possível instalar o xlsx em r.
Cina
22

Muitas respostas boas aqui, mas algumas delas são um pouco desatualizadas. Se você quiser adicionar mais planilhas a um único arquivo, essa é a abordagem que acho que funciona para mim. Para maior clareza, aqui está o fluxo de trabalho para a openxlsxversão 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")

EDITAR

Já experimentei algumas outras respostas e, na verdade, gosto muito do @Syed. Ele não explora todas as funcionalidades do, openxlsxmas se você quiser um método de exportação rápido e fácil, provavelmente esse é o mais simples.

EcologyTom
fonte
8

Não estou familiarizado com o pacote WriteXLS; Eu geralmente uso 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)

Isso certamente pode ser vetorizado, como @joran observou acima, mas apenas para gerar nomes de planilhas dinâmicas rapidamente, usei um forloop para demonstrar.

Usei o create=TRUEargumento in loadWorkbookdesde que estava criando um novo arquivo .xlsx, mas se o seu arquivo já existe, você não precisa especificar isso, pois o valor padrão é FALSE.

Aqui estão algumas capturas de tela da pasta de trabalho criada:

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Nrussell
fonte
1
Não usei o XLConnect, exemplo muito detalhado, obrigado!
Ogre Magi
De nada - descobri que é um pacote muito útil. Há uma vinheta muito boa no CRAN que detalha alguns dos recursos principais, com um bom exemplo na seção 4 demonstrando como escrever gráficos R em uma planilha.
nrussell
5

O tamanho dos dados no caso é pequeno, R tem muitos pacotes e funções que podem ser utilizados conforme sua necessidade.

write.xlsx, write.xlsx2, XLconnect também fazem o trabalho, mas às vezes são lentos em comparação com openxlsx .

Portanto, se você estiver lidando com grandes conjuntos de dados e se deparar com erros de java. Eu sugeriria dar uma olhada no "openxlsx" que é realmente incrível e reduzir o tempo para 1/12 .

Eu testei todos e finalmente fiquei realmente impressionado com o desempenho dos recursos do openxlsx.

Aqui estão as etapas para gravar vários conjuntos de dados em várias planilhas.

 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") deve ser estático, pois faz referência a algum utilitário do Rtools.

Nota: Incase Rtools não está instalado em seu sistema, instale-o primeiro para uma experiência tranquila. aqui está o link para sua referência: (escolha a versão apropriada)

https://cran.r-project.org/bin/windows/Rtools/ marque as opções conforme o link abaixo (é necessário marcar todas as caixas de seleção durante a instalação)

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 pacote é realmente bom para ler e gravar grandes dados de / em arquivos excel e tem muitas opções para formatação personalizada dentro do excel.

O fato interessante é que não precisamos nos preocupar com a memória heap java aqui.

Ayush Varshney
fonte
3

Eu tive exatamente este problema e resolvi desta forma:

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

Dessa forma, você não terá que criar uma lista muito longa manualmente se tiver toneladas de dataframes para gravar no Excel.

alexmathios
fonte
3
Não sei por que isso está substituindo a primeira planilha
Lunalo John
Isso substitui a planilha, eu e outros também enfrentamos o problema. Olhe aqui - stackoverflow.com/questions/57278418/…
Skurup
2

Eu uso regularmente o rio embalado para exportação de todos os tipos. Usando rio, você pode inserir uma lista, nomeando cada guia e especificando o conjunto de dados. rio compila outros pacotes de entrada / saída e, para exportar para Excel, usa openxlsx.

library(rio)

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

export(list(sn1 = tempTable1, sn2 = tempTable2, sn3 = tempTable3), filename)
24lindsey
fonte
0

Para mim, WriteXLS fornece a funcionalidade que você procura. Como você não especificou quais erros ele retorna, mostro um exemplo:

Exemplo

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

Explicação

Se xé:

  • uma lista de frames de dados, cada um é escrito em uma única folha
  • um vetor de caracteres (de objetos R), cada objeto é escrito em uma única folha
  • outra coisa, então veja também o que a ajuda afirma:

Mais sobre o uso

?WriteXLS

mostra:

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

Solução

Para seu exemplo, você precisaria coletar todos os data.frames em uma lista durante o loop e usar WriteXLSdepois que o loop terminar.

Informação da sessão

  • R 3.2.4
  • WriteXLS 4.0.0
setempler
fonte
Este pacote funcionará, mas IMHO, eu tentaria evitar a dependência do perl (assim como tentaria evitar a dependência do Java com xlsx), pois torna mais difícil de configurar
R Yoda
0

Eu faço isso desta forma para openxlsx usando a seguinte função

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)
}
Makarand Kulkarni
fonte
loadWorkbook é a chave aqui para abrir arquivos existentes
makarand kulkarni
Além disso, se alguém quiser escrever fórmulas no Excel, há uma função diferente chamada writeFormula, além disso, uma vez que você escreve a fórmula, o arquivo precisa ser atualizado ou reaberto, salvo e fechado no Excel. demo é dada aqui [link ( stackoverflow.com/questions/46914303/… )
makarand kulkarni
0

Eu faço isso o tempo todo, tudo que eu faço é

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

e todos os frames de dados vêm daqui

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

obviamente, uma rotina inútil seria melhor aqui

Suman C
fonte
0

para uma versão fácil de usar ..

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")
MinimaMoralia
fonte
1
Você poderia adicionar alguma descrição a esta resposta para fornecer contexto de como isso responde à pergunta?
tshimkus