谁能解释一下,为什么在第一个循环中我的日期向量的每个元素都是一个日期,而在第二个循环中,我的日期向量的每个元素都是数字? 谢谢!
x <- as.Date(c("2018-01-01", "2018-01-02", "2018-01-02", "2018-05-06"))
class(x)
# Loop 1 - each element is a Date:
for (i in seq_along(x)) print(class(x[i]))
# Loop 2 - each element is numeric:
for (i in x) print(class(i))
答案 0 :(得分:8)
元素是Date
,第一个循环是正确的。
不幸的是,R并非始终具有第二个循环的样式。我认为问题在于for (i in x)
语法为Date
这样的访问器绕过了[
方法,之所以可以这样做是因为R中的S3类非常薄并且不会阻止您不使用其预期的接口。这可能会造成混淆,因为for (i in 1:4) print(i)
之类的东西直接起作用,因为数值是基本向量类型。 Date
是S3,因此被强制为数字。要查看第二个循环中正在打印的数字对象,可以运行以下命令:
x <- as.Date(c("2018-01-01", "2018-01-02", "2018-01-02", "2018-05-06"))
for (i in x) print(i)
#> [1] 17532
#> [1] 17533
#> [1] 17533
#> [1] 17657
与Date
向量的未分类版本相同。这些数字是自Unix时间开始以来的天数,如果您使用Date
将它们转换回origin
,也可以在下面看到。
unclass(x)
#> [1] 17532 17533 17533 17657
as.Date(unclass(x), "1970-01-01")
#> [1] "2018-01-01" "2018-01-02" "2018-01-02" "2018-05-06"
因此,我会像在第一个循环中一样,坚持对所有S3向量类型使用正确的访问器。
答案 1 :(得分:3)
运行时:
for (i in seq_along(x)) print(class(x[i]))
您正在i
的每个元素上使用迭代器x
。这意味着每次您获得x
的每个迭代成员的类。
但是,当您运行时:
for (i in x) print(class(i))
您正在寻找每个成员的班级。使用?Date
:
日期表示为自1970-01-01以来的天数
这是为什么您将数字作为班级的原因。
此外,如果每个循环都使用print()
,则会得到日期和数字:
for (i in seq_along(x)) print(x[i])
[1] "2018-01-01"
[1] "2018-01-02"
[1] "2018-01-02"
[1] "2018-05-06"
和
for (i in x) print(i)
[1] 17532
[1] 17533
[1] 17533
[1] 17657
最后,如果您想测试R的逻辑,我们可以做这样的事情:
x[1] - as.Date("1970-01-01")
取x的第一个元素(“ 2018-01-01”),然后减去“ 1970-01-01”,这是第一个日期。我们的输出将是:
Time difference of 17532 days
答案 2 :(得分:3)
如果您查看?'for'
,您将看到for(var in seq)
仅在seq
为“表达式为向量的表达式”且is.vector(x)
为{ {1}}。因此,文档说(可能不是很清楚),这里的行为是不确定的,这就是为什么行为是意外的。
正如joran所提到的,FALSE
返回一个数值向量,与Calum You提到的as.vector(x)
相同。