如何在不强制转换为数字的情况下迭代日期列表?

12

这与循环遍历日期或POSIXct对象会导致数字迭代器有关。

> dates <- as.Date(c("2013-01-01", "2013-01-02"))
> class(dates)
[1] "Date"
> for(d in dates) print(class(d))
[1] "numeric"
[1] "numeric"

我有两个问题:

  1. 在迭代日期对象列表时,哪种方法是首选?
  2. 我不理解约书亚(上面链接的接受答案者)的答案,这里引用一下:“因为Date对象不是严格的向量,所以你的Date向量被强制转换为numeric”。那么如何确定应该将Date强制转换为numeric

我的评论的意思是:is.vector(dates) # FALSE,所以日期不是“向量”。你的第二个问题应该是对我之前答案的评论。 - Joshua Ulrich
for循环将其强制转换为向量。 - Joshua Ulrich
1
从帮助页面?vector中可以得知:"对于任何模式,如果x除了names之外还有其他属性,[is.vector]将返回FALSE。" 在R语言中,“向量”并不意味着可以通过位置访问,而是指它没有属性。它明确指出因子不是向量,并且可能还应该指出日期和POSIXt类对象也不是。 - IRTFM
1
回答问题1。您可以将“dates”保留为字符向量,并在循环内强制转换,或者使用您链接的帖子中提到的“seq_along()”技术...(或下面的一个答案) - Justin
1
@JoshuaUlrich @DWin 我认为那不是向量的标准定义。日期是向量,但 is.vector 函数很令人困惑 - 它只告诉你是否有一个没有属性的原子向量。is.atomic(as.Date("2012-01-01")) 是 TRUE,所以日期是原子向量。 - hadley
显示剩余4条评论
1个回答

13

这里有两个问题。一个是输入是否会从Date强制转换为numeric。另一个是输出是否会被强制转换为numeric

输入

对于循环,因为@DWin和@JoshuaUlrich指出,for循环使用的是vectors,而Date在技术上不是向量,所以会将其强制转换为numeric

> for(d in dates) print(class(d))
[1] "numeric"
[1] "numeric"

另一方面,lapply及其简化版本sapply没有此类限制。
> sapply( dates, function(day) class(day) )
[1] "Date" "Date"

输出

然而!上面的class()输出结果是一个字符。如果您尝试返回一个日期对象,sapply并不是您想要的。

lapply不会强制转换为向量,但sapply会:

> lapply( dates, identity )
[[1]]
[1] "2013-01-01"

[[2]]
[1] "2013-01-02"

> sapply( dates, identity )
[1] 15706 15707

那是因为sapply的简化函数将输出强制转换为向量。 摘要 所以:如果您有一个Date对象并想返回一个非Date对象,可以使用lapplysapply。如果您有一个非Date对象并想返回一个Date对象,则可以使用for循环或lapply。如果您有一个Date对象并想返回一个Date对象,请使用lapply学习更多资源 如果您想更深入地了解向量,可以从John Cook的笔记开始,接着阅读R Inferno,再继续学习SDA

1
"sapply"由于使用了"simplify2array"(矩阵只能容纳原子向量)而产生此类问题。您返回的是类,而不是对象本身。请尝试:sapply(Sys.Date(),identity)。虽然"lapply"可以正常工作。 - Joshua Ulrich
1
@user443854:就像我说的那样,它返回对象的类(一个字符字符串,它是一个原子向量),因为它存在于函数调用内部;它并没有返回一个日期。你能允许我把100美元写成“$100”吗? - Joshua Ulrich
2
@JoshuaUlrich 矩阵不仅限于原子向量:matrix(list(1, 2, 3, 4), nrow = 2)。我认为真正的解释是 simplify2array 写得不好,或者日期类缺少必要的 S3 方法。 - hadley
@user443854 行为是完全一致的:如果它是一个 vector(使用 is.vector() 进行测试),那么它就可以工作。 如果不是,那就不能。 R 基本数据类型上有更多的信息。这里可能有人可以推荐一本书(可能以黄色和蓝色为主色调,并由 Chambers 编写),让你学到更多知识。 - Ari B. Friedman
1
@AriB.Friedman @user443854 不,它不是一致的,这是因为for是用C语言编写的,不考虑对象的类,也不使用[来提取向量的单个组件。 - hadley
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接