将 Excel 数字日期转换为 R 日期,但在某些行中只有给定的年份,例如“2018”而不是“43465”

Convert Excel numeric dates to R dates, but in some rows there is only the year given, e.g. "2018" instead of "43465"

我读入了一个 Excel 文件,其中一列包含日期。在某些行中没有完整的日期,但只给出了年份,例如 2018 年。 我在 R 中得到的是

> df$date
[1]    NA    NA 43465 43465 43465 43465  2018    NA 43465 43465 43465 43465

我想将这些行转换为完整日期的日期格式,即在我的示例中只有带有 43465 的行并保持其他行不变,即 NA 应该保持 NA2018 应该保持 2018.

我知道我可以按如下方式转换 Excel 日期 as.Date(df$date, origin="1899-12-30") 但是以下两个想法给我错误的输出

> as.Date(df$date, origin="1899-12-30")
[1] NA NA  "2018-12-31" "2018-12-31" "2018-12-31" "2018-12-31" "1905-07-10" NA "2018-12-31" "2018-12-31" "2018-12-31"
[12] "2018-12-31"

当然"1905-07-10"不是我所期望的

> ifelse(df$date == 2018, 2018, as.Date(df$date, origin="1899-12-30"))
[1]    NA    NA 17896 17896 17896 17896  2018    NA 17896 17896 17896 17896

这里错误的输出很明显。

一个向量不能有多个class。您可以在其中包含数字或日期 class。解决方法是使用最通用的字符 class。

x <- c(NA,NA,43465,43465,43465,43465,2018,NA,43465,43465, 43465, 43465)
ifelse(x == 2018, "2018", as.character(as.Date(x, origin="1899-12-30")))

# [1] NA  NA   "2018-12-31" "2018-12-31" "2018-12-31" "2018-12-31" "2018"      
# [8] NA   "2018-12-31" "2018-12-31" "2018-12-31" "2018-12-31"

然而,一个列表可以有多个 class,所以如果您可以将数据存储在列表中,我们可以使用 lapply

lapply(x, function(y) 
     if (y == 2018 | is.na(y)) y else as.Date(y, origin="1899-12-30"))

根据@Ronak 的回答,您可以使用正则表达式确定一个四​​位数字,然后用四个尾随零填充。

x <- c(NA,NA,43465,43465,43465,43465,2018,NA,43465,43465, 43465, 43465)
ifelse(grepl('^\d{4}$', x, perl = TRUE), 
   as.integer(paste0(x, '0000')), 
   as.integer(format(as.Date(x, origin='1899-12-30'), '%Y%m%d')))
[1]  NA       NA 20181231 20181231 20181231 20181231 20180000       NA 20181231 20181231 20181231 20181231

您会收到一些关于 NA 的警告消息,如果它困扰您,您可以添加额外的 ifelse 来控制 NA。这里我们使用逻辑 grep 测试来查看是否只有四个数字(一年),然后我们创建一个整数值。这允许您仍然使用 ><== 等数学运算符并保​​留所有信息。

您可以根据数据或用例将 paste0() 调用期间的 '0000' 更改为更合适的数字。