我有一个数据框,其中包含一个日期列,我需要将其转换为格式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
提供不同的日期格式?答案 0 :(得分:2)
以下是原始问题第二部分的答案。要获得格式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()
显示此内部表示。
答案 1 :(得分:1)
使用日期时,我喜欢使用lubridate
,因为它在我眼中更容易使用,而且比基本功能更直观。
您可以使用以下代码完成第二个问题:
require(lubridate)
dataframe$Date2<-difftime(dataframe$Date3,dmy("01-01-1970"),units="days")
取决于您是否希望将1970年1月1日作为第1天,您可能需要在此行的末尾添加+1。
我没有直接使用sapply和tapply(我更喜欢使用plyr)所以我无法帮助解决你的第一个问题。
答案 2 :(得分:1)
如果不使用参数simplify=FALSE
,则sapply
将使用命令unlist
将答案从列表转换为向量。 unlist
将列表元素强制为普通类型。来自manual:
在取消列出过程中,可能的情况下,列表元素被强制转换为公共模式,因此结果通常以字符向量结尾。向量将被强制为层次结构中组件的最高类型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"