Таким образом, пакет 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")
Таким образом, после создания начальной книги вы можете просто загрузить ее и изменить листы по отдельности.Поскольку вы упомянули, что вы можете перезаписать наборы данных1 и набор данных2, я сосредоточусь на sumrized_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
преобразует из символьного объекта в числовой объект.
Таким образом, чтобы вызвать эту функцию и обновить таблицу «sumrized_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.
Таким образом, вы можете добавитьна листе "summazed_dat".Перед окончательным сохранением вы также можете обновить первые два листа, повторно выполнив операторы writeDataTable
до того, как мы напишем функцию.Дайте мне знать, если это вообще то, что вы ищете, и я мог бы легко изменить этот код.Удачи!