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

Posted

技术标签:

【中文标题】如何在不强制转换为数字的情况下迭代日期列表?【英文标题】:How to iterate over list of Dates without coercion to numeric? 【发布时间】:2013-01-09 18:09:44 【问题描述】:

这与Looping over a Date or POSIXct object results in a numeric iterator有关

> 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"

我有两个问题:

    迭代 Date 对象列表的首选方法是什么? 我不明白 Joshua 的答案(从上面链接的问题中接受的答案),我会在这里引用它:“所以你的 Date 向量被强制为 numeric 因为 Date 对象不是严格的向量”。那么如何确定Date应该被强制转换为numeric呢?

【问题讨论】:

我的评论的意思是:is.vector(dates) # FALSE,所以日期不是“向量”。您的第二个问题应该是对我之前回答的评论。 很明显dates 不是向量,很明显它是Date。但是是什么让它表现得像一个向量。是什么让它可迭代? 来自帮助页面?vector。 “对于任何模式,如果 x 具有除名称之外的任何属性,它 [is.vector] 将返回 FALSE。”在 R-speak 中,“向量”并不意味着它可以通过位置访问,而是它没有属性。它特别声明因素不是向量,它可能还应该声明 Date 和 POSIXt 分类对象也不是。 回答问题 1。您可以将 dates 保留为字符向量并在循环中强制或使用您链接的帖子中提到的 seq_along() 技术...(或答案之一下面) @JoshuaUlrich @DWin 我不认为这是向量的标准定义。日期是向量,但 is.vector 函数令人困惑 - 它会告诉您是否有一个没有属性的原子向量。 is.atomic(as.Date("2012-01-01")) 为 TRUE,因此日期是原子向量。 【参考方案1】:

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

输入

For 循环将Date 输入强制转换为numeric,因为正如@DWin 和@JoshuaUlrich 指出的那样,for 循环采用vectors,而Dates 在技术上不是向量。

> 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's notes 开始,从R Inferno 继续,然后从SDA 继续。

【讨论】:

sapply 确实如此,因为simplify2array (矩阵只能保存原子向量)。您返回的是类,而不是对象本身。试试:sapply(Sys.Date(), identity)lapply 虽然有效。 打印[1] "Date" "Date"&gt; sapply(dates, class) 怎么样? sapply 不应该强制转换为数字向量吗? (根据帖子和评论) @user443854:正如我所说,这是返回函数调用中存在的对象的类(一个字符串,它是一个原子向量);它没有返回日期。你能允许我给你 100 美元作为“100 美元”吗? @JoshuaUlrich 矩阵不限于原子向量:matrix(list(1, 2, 3, 4), nrow = 2)。我认为真正的解释是 simplify2array 写得不好,或者 Date 类缺少所需的 S3 方法。 @AriB.Friedman @user443854 不是,是不一致的,是因为for是C写的,不看对象的类,还是用[提取向量的各个分量。

以上是关于如何在不强制转换为数字的情况下迭代日期列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不转换为整数的情况下将 null 转换为 int?

为啥我可以键入别名函数并在不强制转换的情况下使用它们?

在PHP中如何强制转化成字符串

是否可以在不强制转换的情况下初始化 float32 或 float16 的随机数组?

如何在不离开 php 页面的情况下强制保存另存为对话框?

如何在不使用列表的情况下转换字符串中的数字?