186  文字列を日付・時刻型へ(sld96)

library(tidyverse)
library(lubridate)

この、 日付、時刻型への変換については、実はas_date関数はかなり優秀で、

as_date("2000/04/30")
[1] "2000-04-30"
as_date("20000430")
[1] "2000-04-30"
as_date("2000年4月30日")
[1] "2000-04-30"

と、日本語表記でも変換できてしまいます。

ただ、

as_date("4月30日(2000年)")
Warning: All formats failed to parse. No formats found.
[1] NA

こんな形であったり、

as_date("04302000")
Warning: All formats failed to parse. No formats found.
[1] NA

こんな形であったりするものは変換できません(数字の順番が大切だったりします)

こういう場合に活躍するのが、数字の並び順に年(year)月(month)、日(day)を指定できる

ymd mdy dmy 等の関数です。

例えば、4月30日(2000年)のような表記は、月、日、年の順番で数字が並んでいるので、

mdy("4月30日(2000年)")
[1] "2000-04-30"

とすることでうまく変換できました。

他に、もっと複雑な変換が必要な場合は、

?parse_date_time
starting httpd help server ... done

の例にあるように、日付と時刻が入り混じっているようなケースや

x <- c("09-01-01", "090102", "09-01 03", "09-01-03 12:02")
as_datetime(x)
Warning: 1 failed to parse.
[1] "2009-01-01 UTC" "2009-01-02 UTC" "2009-01-03 UTC" NA              
parse_date_time(x, c("ymd", "ymd HM"))
[1] "2009-01-01 00:00:00 UTC" "2009-01-02 00:00:00 UTC"
[3] "2009-01-03 00:00:00 UTC" "2009-01-03 12:02:00 UTC"

年月日の順番が途中でいれかわっているようなケース

x <- c("2009-01-01", "02022010", "02-02-2010")
as_date(x)
Warning: 2 failed to parse.
[1] "2009-01-01" NA           NA          
parse_date_time(x, c("dmY", "ymd"))
[1] "2009-01-01 UTC" "2010-02-02 UTC" "2010-02-02 UTC"

何個か欠損しているケース

x <- c("2011-12-31 12:59:59", 
       "2010-01-01 12:11", 
       "2010-01-01 12",
       "2010-01-01")

as_datetime(x)
Warning: 1 failed to parse.
[1] "2011-12-31 12:59:59 UTC" "2020-10-01 01:12:11 UTC"
[3] NA                        "2010-01-01 00:00:00 UTC"
parse_date_time(x, "Ymd HMS", truncated = 3)
[1] "2011-12-31 12:59:59 UTC" "2010-01-01 12:11:00 UTC"
[3] "2010-01-01 12:00:00 UTC" "2010-01-01 00:00:00 UTC"

truncatedで欠損して良い個数を指定するとNAにならずに変換できます。

個人的にはこのparse_date_timeを駆使しないといけないデータが出現した場合は、まずはstr_系の関数を利用して、少しキレイにすることを考えますが、利用できそうな場合は利用できると良いかもしれません。

次は数字から日付型をつくる方法を解説していきます。