R语言 将函数应用于按字符元素的向量

bis0qfac  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(150)

我有一个日期矢量,我从Excel导入,它的格式非常奇怪。其中一些是char形式的dd/mm/yyyy,另一些是char形式的,例如45265,这是excel中与此日期对应的数字。
我想应用一个函数将这个向量转换为R中的正确日期。我尝试的解决方案返回错误,我无法理解它。

t1=c("14/02/2020", "17/02/2020", "18/02/2020", "19/02/2020", "20/02/2020", 
     "21/02/2020", "26/02/2020", "27/02/2020", "28/02/2020", "43864", 
     "43893", "43924", "43954", "43985", "44077")
lapply(t1,function(x) ifelse(grepl("/",x),dmy(x),as.Date(as.numeric(x),origin='1900-01-01')))
31moq8wy

31moq8wy1#

两件事:
1.大部分你想做的事情都可以作为一个向量来做,不需要申请;

  1. ifelse是类不安全的,例如,尝试将它与Date-class(或POSIXt-class)一起使用,将剥离类并返回数字。参见How to prevent ifelse() from turning Date objects into numeric objects
    我建议这是一个替代方案:
out <- rep(as.Date(NA), length(t1))
out[grepl("/", t1)] <- as.Date(t1[grepl("/", t1)], format = "%d/%m/%Y")
out[is.na(out)] <- as.Date(as.numeric(t1[is.na(out)]), origin = "1900-01-01")
out
#  [1] "2020-02-14" "2020-02-17" "2020-02-18" "2020-02-19" "2020-02-20" "2020-02-21" "2020-02-26" "2020-02-27"
#  [9] "2020-02-28" "2020-02-05" "2020-03-05" "2020-04-05" "2020-05-05" "2020-06-05" "2020-09-05"

如果您有更多的候选格式,您可以考虑https://stackoverflow.com/a/52319606/3358272https://stackoverflow.com/a/70304571/3358272,它会迭代可能的格式(以类似的方式),并尝试转换所有格式,直到完成(或耗尽)。
使用base::ifelse(去除类)的替代方案是使用dplyr::if_elsedata.table::fifelse,如果您将任何一个包用于其他用途,这可能会更简单。请注意,它们将在所有t1上运行这两个方法,因此您将得到警告(两个实现)。

if_else(grepl("/", t1), lubridate::dmy(t1), as.Date(as.numeric(t1), origin = "1900-01-01"))
# WARN [2023-05-17 09:54:01] {"msg":"uncaught warning","warning":" 6 failed to parse.","where":["ccbr()","if_else(grepl(\"/\", t1), lubridat","lubridate::dmy(t1)"],"pid":"39316"}
# WARN [2023-05-17 09:54:01] {"msg":"uncaught warning","warning":"NAs introduced by coercion","where":["ccbr()","if_else(grepl(\"/\", t1), lubridat","as.Date(as.numeric(t1), origin ="],"pid":"39316"}
#  [1] "2020-02-14" "2020-02-17" "2020-02-18" "2020-02-19" "2020-02-20" "2020-02-21" "2020-02-26" "2020-02-27"
#  [9] "2020-02-28" "2020-02-05" "2020-03-05" "2020-04-05" "2020-05-05" "2020-06-05" "2020-09-05"
data.table::fifelse(grepl("/", t1), lubridate::dmy(t1), as.Date(as.numeric(t1), origin = "1900-01-01"))
# WARN [2023-05-17 09:54:11] {"msg":"uncaught warning","warning":" 6 failed to parse.","where":["ccbr()","data.table::fifelse(grepl(\"/\", t","lubridate::dmy(t1)"],"pid":"39316"}
# WARN [2023-05-17 09:54:11] {"msg":"uncaught warning","warning":"NAs introduced by coercion","where":["ccbr()","data.table::fifelse(grepl(\"/\", t","as.Date(as.numeric(t1), origin ="],"pid":"39316"}
#  [1] "2020-02-14" "2020-02-17" "2020-02-18" "2020-02-19" "2020-02-20" "2020-02-21" "2020-02-26" "2020-02-27"
#  [9] "2020-02-28" "2020-02-05" "2020-03-05" "2020-04-05" "2020-05-05" "2020-06-05" "2020-09-05"

这可以通过用suppressWarnings包裹整个if_else/fifelse来抑制。

相关问题