如何在不强制转换为数字的情况下迭代日期列表?
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
,而Date
s 在技术上不是向量。
> 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
对象,你可以使用lapply
或sapply
。如果您有一个非Date
对象,并且想要返回一个Date
对象,您可以使用for
循环或lapply
。如果您有一个Date
对象并希望返回一个Date
对象,请使用lapply
。
了解更多信息的资源
如果您想更深入地研究向量,可以从John Cook's notes 开始,从R Inferno 继续,然后从SDA 继续。
【讨论】:
sapply
确实如此,因为simplify2array
(矩阵只能保存原子向量)。您返回的是类,而不是对象本身。试试:sapply(Sys.Date(), identity)
。 lapply
虽然有效。
打印[1] "Date" "Date"
的> sapply(dates, class)
怎么样? sapply
不应该强制转换为数字向量吗? (根据帖子和评论)
@user443854:正如我所说,这是返回函数调用中存在的对象的类(一个字符串,它是一个原子向量);它没有返回日期。你能允许我给你 100 美元作为“100 美元”吗?
@JoshuaUlrich 矩阵不限于原子向量:matrix(list(1, 2, 3, 4), nrow = 2)
。我认为真正的解释是 simplify2array
写得不好,或者 Date 类缺少所需的 S3 方法。
@AriB.Friedman @user443854 不是,是不一致的,是因为for
是C写的,不看对象的类,还是用[
提取向量的各个分量。以上是关于如何在不强制转换为数字的情况下迭代日期列表?的主要内容,如果未能解决你的问题,请参考以下文章