循环 Date 或 POSIXct 对象会产生数字迭代器
为什么迭代 Date
或 POSIXct
对象会产生 numeric
?例如:
test = as.Date("2009-01-01")
print( class( test ) )
# [1] "Date"
for ( day in test )
{
print( class( day ) )
}
# [1] "numeric"
POSIXct
也会发生同样的情况:
test = as.POSIXct("2009-01-01")
print( class( test ) )
# [1] "POSIXct" "POSIXt"
for ( day in test )
{
print( class( day ) )
}
# [1] "numeric"
Why does iterating through a Date
or POSIXct
object result in numeric
? For example:
test = as.Date("2009-01-01")
print( class( test ) )
# [1] "Date"
for ( day in test )
{
print( class( day ) )
}
# [1] "numeric"
The same thing happens with POSIXct
:
test = as.POSIXct("2009-01-01")
print( class( test ) )
# [1] "POSIXct" "POSIXt"
for ( day in test )
{
print( class( day ) )
}
# [1] "numeric"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
?"for"
表示seq
(in
之后的部分)是“[A]n 表达式计算一个向量(包括一个列表和表达式)或配对列表或“NULL””。因此,您的
Date
向量被强制转换为numeric
,因为Date
对象并不是严格意义上的向量:对于
POSIXct
也是如此。代码>向量:?"for"
says thatseq
(the part afterin
) is "[A]n expression evaluating to a vector (including a list and an expression) or to a pairlist or 'NULL'".So your
Date
vector is being coerced tonumeric
becauseDate
objects aren't strictly vectors:The same is true for
POSIXct
vectors:循环天(字符串):
loop through days (strings):
使用 for 循环时,您没有选择正确的函数来应用于
Date
向量。更好的方法是为几乎每个循环的日期或因素包装seq_along
。然后你将做两件事:a) 设置它,以便你期望索引从 1 开始,b) 防止零长度向量发生奇怪的事情。我还认为最好将它与因子一起使用,for 循环会将其转换为字符向量。参考约书亚的答案(这当然是正确且有帮助的),我认为 is.vector 函数有点标签错误或者可能只是被误解了。更准确的说法是
hasNoAttributesOtherThanName
。大多数人认为“矢量”的属性是使用is.atomic
和Date
进行测试的,而POSIXct
对象将返回TRUE
从那个测试中。You are not choosing the right function to apply to
Date
vectors when using for-loops. Better would be wrappingseq_along
for pretty much every date or factor that is being looped across. Then you will do two thing: a) set it up so you are expecting an index that starts at 1, and b) protect against strange things that occur with zero length vectors. I also think it would be better to use it with factors, which the for-loops will turn into character vectors.With reference to Joshua's answer (which is certainly correct and helpful), I think the
is.vector
function is a bit mislabeled or maybe just misunderstood. It could be more accurately be calledhasNoAttributesOtherThanName
. The property that most people consider "vectoric" is tested withis.atomic
andDate
andPOSIXct
objects will returnTRUE
from that test.看来实现 for 循环的 C 函数不会复制向量的任何属性。这还包括
class
属性,它应该使i
看起来是一个Date
对象。您可以研究
do_for(SEXP, SEXP, SEXP, SEXP)
函数的源代码(R的for
调用的函数)此处。It seems that the C function that implements the
for
loop does not copy any of the vector's attributes. This also includes theclass
attribute, which should makei
appear to be aDate
object.You may study the source code of the
do_for(SEXP, SEXP, SEXP, SEXP)
function (the one called by R'sfor
) here.这是一个老问题,但我是 R 新手,也遇到了同样的问题。由于我的问题将并行处理,因此我使用了 foreach 和与正常的
for
相比,看到行为有所不同:由于我对大多数 R 的内部事物没有经验,因此我不知道为什么
foreach
最终有一种不同的行为,但对我的目的有用,希望对别人。It is an old question, but I am a novice on R and faced the same problem. Since my problem would be processed in parallel, I used foreach and saw the behaviour is different when compared with the normal
for
:As I am not experienced with the inner things of most of R, thus I do not know why
foreach
ends up having a different behaviour but that worked for my purpose, and hopefully might be useful for someone else.对日期对象的任何数值运算通常都会返回天数。在此,您要求它为您提供距该纪元的天数。 14245 是 1970-01-01 至 2009-01-01 之间的天数
?日期:
尝试添加
print(day)
来看看我的意思。Any numerical operation on date objects generally returns the number of days. In this, you are asking it to provide you with the number of days from the epoch. 14245 which is the number of days between 1970-01-01 - 2009-01-01
From ?Dates:
Try adding
print(day)
to see what I mean.本身不是一个解决方案,但当您想要检查循环中的日期时,这是一个有用的技巧:
for( i.date in as.character(Sys.Date()) ){
cat(粘贴("日期:", i.date, "\n"))
只需
事先将其转换为字符即可。大多数过滤器不会打扰。
Not a solution per-se, but a useful trick when you want to check the dates in a loop:
for( i.date in as.character(Sys.Date()) ){
cat(paste("Date:", i.date, "\n"))
}
just transform it as character beforehand. Most filters won't bother.