从Excel导入R的日期用不同方式转字符为何结果不同?
关于R中日期列转字符时三种索引方式的差异解答
先来看下背景:用readxl导入带日期的Excel表格后,得到的示例数据是这样的:
# A tibble: 9 x 2 id date <dbl> <dttm> 1 1 2000-01-23 00:00:00 2 2 2000-01-24 00:00:00 3 3 2000-01-25 00:00:00 4 4 2000-01-26 00:00:00 5 5 2000-01-27 00:00:00 6 6 2000-01-28 00:00:00 7 7 2000-01-29 00:00:00 8 8 2000-01-30 00:00:00 9 9 2000-01-31 00:00:00
当尝试把date列转换成字符时,三种索引方式得到了完全不同的结果:
1. 使用$索引
> as.character(dat$date) [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27" [6] "2000-01-28" "2000-01-29" "2000-01-30" "2000-01-31"
2. 使用[[ ]]索引
> as.character(dat[[2]]) [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27" [6] "2000-01-28" "2000-01-29" "2000-01-30" "2000-01-31"
3. 使用[ , ]索引
> as.character(dat[ , 2]) [1] "c(948585600, 948672000, 948758400, 948844800, 948931200, 949017600, 949104000, 949190400, 949276800)"
为什么第三种方式结果不同?
核心原因是三种索引返回的对象类型完全不一样:
dat$date和dat[[2]]返回的是单一的POSIXct日期向量——这是R里用来存储时间序列的原子向量类型。当你对向量调用as.character()时,R会逐个处理向量里的每个元素,把每个日期转换成人类可读的"YYYY-MM-DD"字符格式。- 而
dat[,2]返回的是一个只有一列的数据框(data frame)。当你对整个数据框调用as.character()时,R不会遍历每一个元素转换,而是直接输出这个数据框的底层存储形式——也就是日期对应的UNIX时间戳。
那些数字是什么来源?
你看到的一串数字是UNIX时间戳,它的定义是从1970年1月1日00:00:00 UTC到目标日期的总秒数。比如第一个数字948585600,计算下来正好对应2000年1月23日0点整。
至于和Excel日期数字不对应,是因为Excel的日期计数起点是1900年(Windows默认)或1904年(Mac旧版默认),和R的POSIXct类型用的UNIX时间戳起点完全不同,所以数值自然没法对应上。
补充:怎么让第三种方式得到和前两种一样的结果?
如果想用[ , ]索引还得到正确的字符格式,只需要加上drop=TRUE参数,让R把单列数据框自动转换成向量:
> as.character(dat[ , 2, drop=TRUE]) [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27" [6] "2000-01-28" "2000-01-29" "2000-01-30" "2000-01-31"
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

