我正在努力转换许多不同格式类型的字符类日期(例如,yyyy / mm / dd; mm / dd / yyyy; yyyy-mm-dd; mm-dd-yyyy; yy-mm-dd; mm-dd-yy;等)到POSIXlt类。理想情况下,我想将所有birth_dates转换为具有yyyy / mm / dd格式的POSIXlt类(请参阅下面的示例数据)。在R?中有没有简单的方法呢?
id birth_date start_date age
102 08/09/1993 2013/09/01 20
103 1995-02-21 2013/09/01 18
104 01-15-94 2013/09/01 19
105 88-12-30 2013/09/01 24
这是我到目前为止所做的事情。不幸的是,考虑到原始日期格式化的所有不同方式,这似乎不起作用(我结束了比应有的更多的NAs):
library(lubridate)
data$birth_date1<-as.Date(data$birth_date,format="%Y-%m-%d") #Convert character class to date class
data$birth_date2<-ymd(swc3$birth_date1) #Convert date class to POSIXlt class using lubridate pkg
答案 0 :(得分:1)
那太可怕了。可能会更糟糕。至少在那里有分隔符,如“ - ”和“/".
是的,有一种简单的方法可以在R中解析它。将parse_date_time()
分别应用于每个出生日期,给它一个合适的orders
列表供选择,并仔细设置猜测的顺序。完成后,您需要将“整数时间”转换为有用的时间。
有关详细信息,请参阅完整答案。
这就是lubridate
包有parse_date_time()
的原因。但是有问题。我们来看看:
require(lubridate)
# WRONG! doesn't work as intended.
as.Date(
parse_date_time(data$birth_date,
orders=c("ymd", "mdy", "mdY", "Ymd")
)
)
[1] "1993-08-09" "1995-02-21" "1994-01-15" "0088-12-30"
除了最后一个,这看起来很棒。发生了什么事?
parse_date_time()
正在选择在解析日期时使用的“最适合”的订单和格式集,最后一个元素是奇数的。
为了使这项工作按预期进行,您需要逐个应用parse_date_time()
到每个日期,因为每个日期格式显然是随机选择或多或少。这会慢一些,但会提供更多有用的答案。
# RIGHT. Some conversion of results required.
parsed <- sapply(data[,"birth_date"],
parse_date_time,
orders=c("ymd", "mdy", "mdY", "Ymd") )
parsed
08/09/1993 1995-02-21 01-15-94 88-12-30 744854400 793324800 758592000 599443200
好的,那些看起来像Unix时间整数,它是unclass()
生成的parse_date_time()
'版本。没有一个是消极的,所以它们必须在1970年之后发生。这是令人鼓舞的。转换:
# Conversion of results
parsed <- as.POSIXct(parsed, origin="1970-01-01", tz = "GMT")
as.Date(parsed)
08/09/1993 1995-02-21 01-15-94 88-12-30 "1993-08-09" "1995-02-21" "1994-01-15" "1988-12-30"
lubridate
和parse_date_time()
非常擅长他们的工作。
由于您要求POSIXlt,而不是日期类型:
as.POSIXlt(parsed)
08/09/1993 1995-02-21 "1993-08-09 10:00:00 AEST" "1995-02-21 11:00:00 AEDT" 01-15-94 88-12-30 "1994-01-15 11:00:00 AEDT" "1988-12-30 11:00:00 AEDT"
虽然我个人更喜欢只有实际时间不重要的日期;假设这些都发生在UTC的午夜,并转换为我的时区(澳大利亚东部)。