【问题标题】:writing data in to excel with title above header - R将数据写入excel,标题在标题上方 - R
【发布时间】:2018-04-30 16:38:41
【问题描述】:

这是我的 Excel 输出在一张表中的样子,

Total Expenses

Region Jan-18 Feb-18 Mar-18 
Reg1   32     65     56
Reg2   24     45     89
Reg3   15     78     23

Average Expenses

Region Jan-18 Feb-18 Mar-18
Reg1    12    14     13
Reg2    13    15     14
Reg3    11    14     12

我在 R 中使用 rbind 构造它,首先添加标题和相应的数据集,然后添加空行,然后添加数据集。但是,通过这样做,我失去了实际数据的数字性质。我们可以在为我的数字保留数字数据类型的同时做到这一点吗?

注意:上面是要写入一张 excel 的示例数据,同样我正在构建 4 个不同的表格作为数据框列表并使用 write.xlsx 输出它们。

【问题讨论】:

  • 获得完美解决方案并不容易:通过THIS IDEA 和一些关于HEREDataFormat()CellStyle 的研究,您可以获得一些东西。

标签: r


【解决方案1】:

这是一个使用 xlsx 包的工作示例:

totExpenses <- data.frame('Region'=c('Reg1','Reg2','Reg3'),
                          'Jan-18'=c(32,24,15),
                          'Feb-18'=c(65,45,78),
                          'Mar-18'=c(56,89,23),check.names=FALSE)
avgExpenses <- data.frame('Region'=c('Reg1','Reg2','Reg3'),
                          'Jan-18'=c(12,13,11),
                          'Feb-18'=c(14,15,14),
                          'Mar-18'=c(13,14,12),check.names=FALSE)


library(xlsx)

wb <- createWorkbook()
sh <- createSheet(wb,"mySheet")
row <- 1
addDataFrame(data.frame("Total Expenses"=double(),check.names=FALSE),
             sheet = sh,startRow=row,row.names=FALSE)
row <- row + 2
addDataFrame(totExpenses,sheet=sh,startRow=row,row.names=FALSE)
row <- row + nrow(totExpenses) + 2
addDataFrame(data.frame("Average Expenses"=double(),check.names=FALSE),
             sheet=sh,startRow=row,row.names=FALSE)
row <- row + 2
addDataFrame(avgExpenses,sheet=sh,startRow=row,row.names=FALSE)
saveWorkbook(wb,file='myfile.xlsx')

结果:


这是一个自定义函数,它采用 data.frame 的命名列表并将它们写入具有所需结构的 excel 工作表:

writeListOfDFToSheet <- function(lst,workBook,sheetName){

  sh <- createSheet(workBook,sheetName)

  # force names in list if not present
  if(is.null(names(lst))) 
    names(lst) <- rep.int("",length(lst))
  names(lst) <- ifelse(names(lst) == "",paste("data.frame",1:length(lst)),names(lst))

  row <- 1
  for(i in seq_len(length(lst))){
    DFName <- names(lst)[i]
    DF <- as.data.frame(lst[[i]])

    # header
    addDataFrame(setNames(data.frame(x=logical()),DFName),
                 sheet=sh,startRow=row,row.names=FALSE)
    row <- row + 2

    # data.frame
    addDataFrame(DF,
                 sheet=sh,startRow=row,row.names=FALSE)
    row <- row + nrow(DF) + 2
  }

  invisible(NULL)
}

使用示例(假设前 2 个 data.frame 被定义):

# create a workbook 
wb <- createWorkbook()

# write to "sheet 1" 
lst1 <- list("Total Expenses"=totExpenses,"Average Expenses"=avgExpenses)
writeListOfDFToSheet(lst1,wb,"sheet 1")

# write to "sheet 2" 
# (I'm using the same data.frame's but it's just an example)
lst2 <- list("Total Expenses"=totExpenses,"Average Expenses"=avgExpenses)
writeListOfDFToSheet(lst2,wb,"sheet 2")

# save excel file
saveWorkbook(wb,file='myfile.xlsx')

【讨论】:

  • 感谢您对此的帮助。我需要在一张表中写入一些数据框,在另一张表中写入一些数据框,等等。如何在此自定义函数中添加多个表。 ?
  • @ds_user :更改了功能。无论如何,这个想法是您创建一个工作簿,创建一个工作表,然后使用 addDataFrame 写入它
  • 太棒了。谢谢。
【解决方案2】:

将您的 df 转换为列表,您可以使用此代码:

install.packages("devtools")
library(devtools)

# Install package from github
install_github('d-notebook/sheetr')
library(sheetr)

# Create a list of dataframes
iris_dataframe = list()
iris_dataframe[["Setosa subset"]] = head(iris[iris$Species == "setosa",])
iris_dataframe[["Versicolor subset"]] = head(iris[iris$Species == "versicolor",])

# Write the list of dataframes to CSV file
write_dataframes_to_csv(iris_dataframe, "exmaple_csv.csv")

【讨论】:

  • 嗨。谢谢你的帮助。他可以在这里面有多张床单吗?一些数据框在一张纸上,一些在另一张纸上,等等?
  • 不,您不能有多个 csv 格式的工作表。但是,.xlsx 格式文件可以有多个工作表。 @ds_user
  • 是的。我只需要用 xlsx 编写它。这个解决方案可以扩展为 excel 吗?
  • 这应该可以。我不知道。我还没有测试过。 write.xlsx(df, file = 'file.xlsx', sheetName = 'sheet 1',append=TRUE) @ds_user
  • @digEmAll 的解决方案完美运行。无论如何感谢您的帮助。 :)
【解决方案3】:

我发现了一些有趣的东西,值得在这里分享:

您可以通过使用正确的类型将列添加为list 来归档您想要的结果:

看看这个例子:

df       <- data.frame(a=1:5)
df$normal<- c(1,"two",3,4,5)
#add Column as list
df$new   <- list("title",NA,1,2,"three")
#look at your xlsx-file. Column "new" has the right types!
xlsx::write.xlsx(x = df,file = "new.df.xlsx")

所以这里有一个与你的情况相匹配的例子

df <- rbind(c("title",rep(NA,4)),rep(NA,5),mtcars[1:5,1:5],c("title2",rep(NA,4)),rep(NA,5),mtcars[1:5,1:5])
xlsx::write.xlsx(x = df,file = "stupidResult.xlsx")

df.list <-lapply(matrix(df),function(x)lapply(x,function(i){type.convert(as.character(i), as.is = TRUE)}))

df.new<-data.frame(dummy=1:nrow(df)) 
for(i in seq_along(df)) {df.new[[i]]<-df.list[[i]]}
names(df.new) <- names(df)
xlsx::write.xlsx(x = df.new,file = "superResult.xlsx")

只需将df 替换为您的data.frame

【讨论】:

  • 感谢您的时间和帮助。 :)
猜你喜欢
  • 2016-04-18
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
相关资源
最近更新 更多