在R中转换为日期类型从2017 Apr到2017-04-01

时间:2019-11-22 22:46:27

标签: r

我正在尝试将以下内容转换为R中的数据对象,以使其月份的第一天为“ 2017-04-01”,“ 2015,-07-01”,“ 2014-09-01”等

我尝试过拆分列并使用:

mutate(numeric_month = match(month, month.abb))

数据

c("2017 Apr", "2015 Jul", "2014 Sep", "2014 Sep", "2016 Jun", "2015 Mar", "2016 Jul", "2017 Jan", "2014 Dec")

2 个答案:

答案 0 :(得分:3)

使用lubridatetruncated参数很容易实现。

library(magrittr)
c("2017 Apr", "2015 Jul", "2014 Sep", "2014 Sep", "2016 Jun", "2015 Mar", "2016 Jul", "2017 Jan", "2014 Dec") %>% 
  lubridate::ymd(truncated = 1)

编辑: 关于truncated参数的注释:

lubridate具有许多功能,您可以轻松地仅定义日期/日期时间信息的存储顺序。但是,它并不涵盖所有可能的情况。例如,没有针对您的特定情况的ym()函数,但基本上被截断表示您可能缺少多少日期部分。

如果数据不一致(有时会给出较少的信息),这也很有用。在此处检查是否将truncated设置为12

c("2017 Apr", "2015 Jul", "2014 ", "2014 Sep", "2016 Jun", "2015 Mar", "2016 Jul", "2017 Jan", "2014 Dec") %>% 
  lubridate::ymd(truncated = 2)

答案 1 :(得分:3)

  

预先:这并不是要代替@wusel的答案,我借来了truncated=1;更多-因此这是为了扩大决策范围并为决策提供依据。尽管lubridate和相关的软件包通常是一个快速的答案,但是理解基本的R方法也可能是很好的(有时甚至是首选)。


有几种软件包可以很好地“猜测”格式,包括lubridateanytime。这些通常处理(足够好)在人类生成的数据中常见的可变格式。

有时候,它们的功能更快,但并非总是如此。例如,使用9个元素的样本vec,下面的基本R方法快100倍。 lubridate::ymd直到大约9000个元素才达到奇偶校验,这时它与基本R解决方案一样快。

如果您担心外部库的依赖性,那么基本的R解决方案可能就足够了:

vec <- c("2017 Apr", "2015 Jul", "2014 Sep", "2014 Sep", "2016 Jun", "2015 Mar", "2016 Jul", "2017 Jan", "2014 Dec")
as.Date(paste(vec, "01"), format = "%Y %b %d") 
# [1] "2017-04-01" "2015-07-01" "2014-09-01" "2014-09-01" "2016-06-01"
# [6] "2015-03-01" "2016-07-01" "2017-01-01" "2014-12-01"

性能可能是一个问题,并且外部库的启动并不总是比base R快。例如,请参见下面的基准。 (为简洁起见,我省略了除第一个电话以外的所有电话机对microbenchmark的调用。)

ovec <- vec # for easy replication

vec <- ovec # unmodified, length 9
microbenchmark::microbenchmark(
  base=as.Date(paste(vec, "01"), format = "%Y %b %d"),
  lub=lubridate::ymd(vec, truncated=1),
  any=anytime::anydate(vec)
)
# Unit: microseconds
#  expr    min      lq     mean  median      uq    max neval
#  base   24.8   32.75   44.030   40.65   48.45   96.6   100
#   lub 1930.2 2220.15 2493.421 2470.70 2600.55 3988.9   100
#   any  843.4 1028.55 1100.802 1064.70 1117.35 1786.7   100

vec <- rep(ovec, 100) # length 900
# Unit: milliseconds
#  expr     min       lq      mean   median      uq     max neval
#  base  1.0186  1.03205  1.077106  1.05280  1.0821  1.7377   100
#   lub  3.7256  3.85880  4.078732  3.99555  4.1191  7.6760   100
#   any 80.2832 81.01845 81.866035 81.38680 82.0539 94.5261   100

vec <- rep(ovec, 1000) # length 9000
# Unit: milliseconds
#  expr      min        lq      mean    median        uq       max neval
#  base  10.0675  10.21355  10.54913  10.34485  10.61695   13.6982   100
#   lub   9.9044  10.17945  10.57318  10.29240  10.57785   13.3987   100
#   any 809.8678 820.55190 842.60012 825.04555 845.02495 1132.2419   100

(我可能对anytime做错了,我希望在输入的情况下它会飞得更快。如果我遗漏了一些东西,我会提出建议以改善这种比较。)

如您所见,lubridate解决方案在数据长度为9000的同时运行。对于咯咯笑的情况,lubridate::ymd解决方案的性能要好10倍(省去{{1 }}):

anytime