【问题标题】:When writing to an excel sheet, how can I add a new row each time I run the script?写入 Excel 工作表时,如何在每次运行脚本时添加新行?
【发布时间】:2019-06-12 02:44:16
【问题描述】:

我编写了一个脚本,可以定期从 2 个数据库中提取和汇总数据。我正在使用write.xlsx 将 3 个数据帧写入 3 个不同的选项卡:

  • Tab1 是来自一个数据库的数据,
  • Tab2 是另一个数据,并且
  • Tab3 是两者的汇总数据。

如果每次运行都覆盖选项卡 1 和 2 很好,但我希望 Tab3 每次运行都添加一个新行(在 col1 中带有 sys.date),从而为我提供数据摘要的历史记录。这可能吗?如何实现?

append=TRUE 没有得到我想要的东西。我的下一个选项(不太理想)是将汇总数据写入文件名中带有 sys.date 的单独文件。

# Write to spreadsheet w/ 3 tabs
write.xlsx(df1, file = "file_location\\filename.xlsx", sheetName = "dataset1", row.names = FALSE, append = FALSE) #write to tab1

write.xlsx(df2, file = "file_location\\filename.xlsx", sheetName = "dataset2", row.names = FALSE, append = TRUE) #write to tab2

write.xlsx(summary_df, file = "file_location\\filename.xlsx", sheetName = "summarized_data", row.names = FALSE, append = TRUE) #write to next blank row in tab3

脚本会在每次运行时覆盖汇总数据。我希望它附加到下一个空白行。

【问题讨论】:

    标签: r dataframe r-xlsx


    【解决方案1】:

    所以openxlsx 包不仅允许您指定要附加新数据的行,还可以提取当前工作簿工作表的最后一行。诀窍是将日期和新的摘要数据写入DataTable 对象,这是openxlsx 包所独有的。函数 writeDataTable 将允许您执行此操作,唯一需要的参数是工作簿对象的名称、工作簿中工作表的名称和任何 R data.frame 对象。可以使用 loadWorkbook 函数获取工作簿对象,该函数只需获取 Excel 文件名的路径。您还可以读取包含多个工作表的整个 Excel 工作簿,然后提取和修改各个工作表,然后将它们保存回原始 Excel 工作簿。

    要创建初始工作簿以使更新与原始工作簿兼容,只需将 write.xlsx 语句替换为 writeDataTable 语句,如下所示:

        library(openxlsx)
        wb <- createWorkbook()
        writeDataTable(wb,sheet="dataset1",x=dataset1)
        writeDataTable(wb,sheet="dataset2",x=dataset2)
        writeDataTable(wb,sheet="summarized_dat",x=summary_df)
        saveWorkbook(wb,"file_location\\filename.xlsx")
    

    因此,在创建初始工作簿后,您现在可以简单地加载该工作簿并单独修改工作表。既然你提到你可以覆盖 dataset1 和 dataset2 我将专注于 summary_dat 因为你可以使用上面的代码覆盖以前的数据集:

        library(openxlsx)
        wb <- loadWorkbook("file_location\\filename.xlsx")
    

    现在您可以使用下面的函数将新的汇总数据附加到日期中。为此,我将日期转换为 data.frame 对象,但您也可以使用 writeData 函数。我喜欢writeDataTable 函数,因为您可以使用getTables 更轻松地提取最后一行。以我的一个工作簿为例,调用getTables 的输出如下所示,其中三个表格垂直堆叠:

        [1] "A1:P61"   "A62:A63"  "A64:T124"
    

    然后诀窍是提取最后一行编号,在本例中为 124。所以这是我刚刚快速编写的一个函数,它将自动为您完成所有这些操作,并获取一个工作簿对象,您希望的工作表名称进行修改,并将更新后的汇总表保存为data.frame对象:

        Update_wb_fun<-function(wb, sheetname, newdata){
    
            tmp_wb <- wb #creates copy if you wish to keep the original before modifying as a check
    
            table_cells <- names(getTables(tmp_wb,sheetname)) #Extracts the Excel cells for all DataTables in the worksheet. First run there will only be one but in subsequent runs there will be more and you will want the last one.
    
            lastrow <- as.numeric(gsub("[A-z]","",unlist(strsplit(table_cells[length(table_cells)],":"))[2])) #Extracts the last row
    
            start_time_row <- lastrow+1
    
            writeDataTable(tmp_wb,sheet=sheetname,x=data.frame(Sys.Date()),startRow = start_time_row) #Appending the time stamp as DatTable.
    
            writeDataTable(tmp_wb,sheet=sheetname,x=newdata,startRow = start_time_row+2) #Appending the new data under the time stamp
    
            return(tmp_wb)
        }
    

    提取“lastrow”的代码看起来有点复杂,但使用基本 R 函数来提取该行号。 length 函数从上面的示例输出中提取最后一个元素(例如,“A64:T124”)。 strsplit 用冒号分隔字符串,我们必须 unlist 这个来创建一个向量并获得第二个元素(例如,“T124”)。最后gsub 删除字母并只保留行号(例如,“124”)。 as.numeric 将字符对象转换为数字对象。

    因此,要调用此函数并更新“summarized_dat”工作表,请执行以下操作:

        test_wb <- Update_wb_fun(wb, "summarized_dat", summary_df) #Here I am preserving the original workbook object before modification but you could save to wb directly.
    
        saveWorkbook(test_wb, "file_location\\filename.xlsx", overWrite=T) #Need to use the overWrite option if filename already exists.
    

    这就是您可以附加到“summarized_dat”表的方式。在最终保存之前,您还可以通过在我们编写函数之前重新运行writeDataTable 语句来更新前两张表。让我知道这是否正是您要查找的内容,我可以轻松修改此代码。祝你好运!

    【讨论】:

      【解决方案2】:

      我会查看 openxlsx 包 - 它允许您从 Excel 文件中的给定行开始写入数据。唯一需要注意的是,您需要读取当前 Excel 文件以确定哪一行是包含数据的最后一行。您可以使用 readxl 包并使用从 Excel 文件创建的数据框的 nrow() 来确定行数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-27
        • 2014-02-03
        • 2019-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 2017-07-14
        相关资源
        最近更新 更多