从 R 到 Excel 的日期转换(有时会有一天的偏移)
Date Conversion from R to Excel (sometimes there is a shift by one day)
我正在从事一个 R 项目,其中一个目标是创建 Excel Sheets。
问题是某些日期值(旧值)有一天的变化,但其他值运行良好!
显示的代码创建了一个 data.frame,其中包含一个名为 Dates 的列。在此列中存储值 01.01.1900、01.01.1950 和 01.01.2000。创建 Excel Sheet 后,01.01.1900 更改为 02.01.1900,其他保持不变。
dates = as.Date(c("01.01.1900","01.01.1950","01.01.2000"), "%d.%m.%Y")
df = data.frame(Dates=dates)
wb <- createWorkbook()
addWorksheet(wb, sheetName = "Dates")
writeData(wb, 1, df)
saveWorkbook(wb, "dates.xlsx", overwrite = TRUE)
如果有人能向我解释为什么会这样,最好能提供解决方案。
一切顺利,
安迪
被称为Excel的leap-year bug。它错误地假定 29/02/1900 是实际的一天。但是,它是故意这样实现的,以确保与 Lotus 1-2-3 电子表格的兼容性。
因此,您会发现 01/01/1900 和 28/02/1900 之间的任何日期都会出现此问题。当用 R 写入电子表格时,它会将日期向前移动 1 天,而当从电子表格中读取时,它应该将日期向后移动 1 天。
在 openxlsx 的 github 上有一个未解决的问题 - 因此将来可能会修复此问题。参见:openxlsx github issue
一般来说,我觉得应该很少需要在这个日期范围内写日期。除了作为缺失日期的占位符之外。
不过,如果您需要解决方法,您始终可以编写一个小函数,在写入 excel 之前手动将受影响的日期增加 1 天。例如:
library(tidyverse)
library(lubridate)
library(openxlsx)
# Helper Function
fix_dates_for_excel_write <- function(df) {
df %>%
as_tibble() %>%
mutate_if(is.Date, ~ if_else(. <= ymd(19000228), . - days(1), .))
}
# Affected dates to test
dates = as.Date(c("01.01.1900", "02.01.1900",
"27.02.1900", "28.02.1900",
"01.03.1900", "01.01.1950"), "%d.%m.%Y")
df = data.frame(Dates=dates)
# Apply helper function
df <- fix_dates_for_excel_write(df)
# Write to Excel
writeData(wb, 1, df)
我正在从事一个 R 项目,其中一个目标是创建 Excel Sheets。 问题是某些日期值(旧值)有一天的变化,但其他值运行良好!
显示的代码创建了一个 data.frame,其中包含一个名为 Dates 的列。在此列中存储值 01.01.1900、01.01.1950 和 01.01.2000。创建 Excel Sheet 后,01.01.1900 更改为 02.01.1900,其他保持不变。
dates = as.Date(c("01.01.1900","01.01.1950","01.01.2000"), "%d.%m.%Y")
df = data.frame(Dates=dates)
wb <- createWorkbook()
addWorksheet(wb, sheetName = "Dates")
writeData(wb, 1, df)
saveWorkbook(wb, "dates.xlsx", overwrite = TRUE)
如果有人能向我解释为什么会这样,最好能提供解决方案。
一切顺利, 安迪
被称为Excel的leap-year bug。它错误地假定 29/02/1900 是实际的一天。但是,它是故意这样实现的,以确保与 Lotus 1-2-3 电子表格的兼容性。
因此,您会发现 01/01/1900 和 28/02/1900 之间的任何日期都会出现此问题。当用 R 写入电子表格时,它会将日期向前移动 1 天,而当从电子表格中读取时,它应该将日期向后移动 1 天。
在 openxlsx 的 github 上有一个未解决的问题 - 因此将来可能会修复此问题。参见:openxlsx github issue
一般来说,我觉得应该很少需要在这个日期范围内写日期。除了作为缺失日期的占位符之外。
不过,如果您需要解决方法,您始终可以编写一个小函数,在写入 excel 之前手动将受影响的日期增加 1 天。例如:
library(tidyverse)
library(lubridate)
library(openxlsx)
# Helper Function
fix_dates_for_excel_write <- function(df) {
df %>%
as_tibble() %>%
mutate_if(is.Date, ~ if_else(. <= ymd(19000228), . - days(1), .))
}
# Affected dates to test
dates = as.Date(c("01.01.1900", "02.01.1900",
"27.02.1900", "28.02.1900",
"01.03.1900", "01.01.1950"), "%d.%m.%Y")
df = data.frame(Dates=dates)
# Apply helper function
df <- fix_dates_for_excel_write(df)
# Write to Excel
writeData(wb, 1, df)