我有一个带有日期列的数据框,我需要将其转换为 R 识别为日期的格式。
> dataframe
Date Sum
1 06/09/15 2.51
2 06/09/15 3.75
3 06/09/15 3.50
...
我首先使用 sapply
转换它:
> dataframe$Date2<-sapply(dataframe$Date,as.Date,format="%m/%d/%y")
这将返回日期作为从 1970 年 1 月 1 日开始的天数:
> dataframe
Date Sum Date2
1 06/09/15 2.51 16595
2 06/09/15 3.75 16595
3 06/09/15 3.50 16595
...
后来我尝试在没有sapply
的情况下转换它:
> dataframe$Date3<-as.Date(dataframe$Date,format="%m/%m/%d")
这反过来又返回了
> dataframe
Date Sum Date2 Date3
1 06/09/15 2.51 16595 2015-09-15
2 06/09/15 3.75 16595 2015-09-15
3 06/09/15 3.50 16595 2015-09-15
...
这是两种非常不同、显然不兼容的格式。为什么sapply
返回一种格式(自原点以来的几天),而不返回另一种格式(%Y-%m-%d)?
现在,显然我可以忽略一种方法,并且永远不会使用sapply
与as.Date
,但我想知道为什么它的读法不同。我也在努力将 Date3 矢量转换为 Date2 格式。
因此,我有两个问题:
- 为什么
sapply
提供不同的日期格式? - 如何将日期可识别的序列(例如 mm/dd/yyyy)转换为自 1970 年 1 月 1 日以来的天数?
这是对原始问题的第二部分的回答。 要以mm/dd/yyyy
格式获取日期自纪元(1970 年 1 月 1 日)以来的天数,您可以使用 as.Date()
函数:
some.date <- as.Date("06/17/2015", "%m/%d/%Y")
days.since.epoch <- unclass(some.date)
> days.since.epoch
[1] 16616
在内部,R 根据纪元(1970 年 1 月 1 日)以来的天数存储日期对象some.date
,调用 unclass()
会显示此内部表示形式。
在使用日期时,我喜欢使用lubridate
,因为它在我看来比基本函数更容易使用和直观。
您的第二个问题可以使用以下代码完成:
require(lubridate)
dataframe$Date2<-difftime(dataframe$Date3,dmy("01-01-1970"),units="days")
取决于您是否要 1.1970 年 1 月是否为第 1 天,您可能需要在此行的末尾添加 +1。
我并没有真正直接使用 sapply 和 tapply(我更喜欢为此使用 plyr),所以我无法帮助您回答第一个问题。
1.
如果不使用参数 simplify=FALSE
,sapply
将使用命令 unlist
将答案从列表转换为向量。 unlist
强制列表元素为通用类型。从手册:
在可能的情况下,列表元素在取消列出期间被强制为共模,因此结果通常最终会成为字符向量。向量将被强制到层次结构中最高类型的组件 NULL <原始><逻辑><整数><双倍><复杂><字符><列表><表达式:对列表被视为列表。>列表>字符>复杂>双倍>整数>逻辑>原始>
因为Date
不是等级制度的一部分,unlist
不能强迫Date
。我不确定为什么unlist
选择强制使用整数(而不是字符),但这可能与Date
对象存储为整数的事实有关。
阿拉伯数字。
要将Date
转换为自 1970 年 1 月 1 日以来的天数,可以使用as.numeric
today=Sys.Date()
> today
[1] "2019-04-16"
> as.numeric(today)
[1] 18002
并返回
> as.Date(18002, origin="1970-01-01")
[1] "2019-04-16"