循环使用datetime对象会生成数字迭代器

SFu*_*n28 43 attributes for-loop r date

为什么迭代一个Date或一个POSIXct对象导致numeric?例如:

test = as.Date("2009-01-01")
print( class( test ) )
# [1] "Date"
for ( day in test )
{
    print( class( day ) )
}
# [1] "numeric"
Run Code Online (Sandbox Code Playgroud)

同样的事情发生在POSIXct:

test = as.POSIXct("2009-01-01")
print( class( test ) )
# [1] "POSIXct" "POSIXt"
for ( day in test )
{
    print( class( day ) )
}
# [1] "numeric"
Run Code Online (Sandbox Code Playgroud)

Jos*_*ich 34

?"for"seq(后面的部分in)是"[A] n表达式,用于评估向量(包括列表和表达式)或向载体或"NULL"进行评估.

所以你的Date矢量被强制执行,numeric因为Date对象不是严格的向量:

is.vector(Sys.Date())
# [1] FALSE
is.vector(as.numeric(Sys.Date()))
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

POSIXct矢量也是如此:

is.vector(Sys.time())
# [1] FALSE
is.vector(as.numeric(Sys.time()))
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

  • 非常接近,但恐怕这里的 for 循环中没有强制,请参阅 [this answer](http://stackoverflow.com/a/23278464/3309529)..... (2认同)
  • @gagolews:这是一个非常微妙的区别,很少有人会理解或欣赏。是的,`for` 不会剥离属性并在迭代器上调用 `coerceVector`(并可能创建一个副本)。它只是忽略属性。不管怎样,实际效果是一样的。如果我说“被视为”而不是“被迫”,你就没有意义了。 (2认同)
  • @gagolews:不要误会我的评论,这很有趣,但是我只是认为大多数人都不会在意。;) (2认同)

小智 22

循环天(字符串):

     days <- seq(from=as.Date('2011-02-01'), to=as.Date("2011-03-02"),by='days' )
     for ( i in seq_along(days) )
     {
          print(i)
           print(days[i])
      }
Run Code Online (Sandbox Code Playgroud)


42-*_*42- 19

Date在使用for循环时,您没有选择正确的函数应用于向量.更好的是包装seq_along几乎每个日期或因素循环.然后你会做两件事:a)设置它以便你期望一个从1开始的索引,和b)防止零长度向量发生的奇怪事情.我也认为最好将它与因子一起使用,因为for循环将变成字符向量.

关于约书亚的答案(肯定是正确和有帮助的),我认为这个is.vector功能有点被误标或者可能只是被误解了.它可以更准确地被称为hasNoAttributesOtherThanName.大多数人认为"vectoric"的性质与测试is.atomic,并DatePOSIXct对象将返回TRUE从测试.

  • +1特别是对于`hasNoAttributesOtherThanName`,虽然我认为它应该命名为`has_no_attributes_other_than_name`.;-) (3认同)

gag*_*ews 7

似乎实现for循环的C函数不会复制任何向量的属性.这还包括class属性,该属性应该i看起来像是一个Date对象.

你可以学习的源代码do_for(SEXP, SEXP, SEXP, SEXP)功能(一个由R的称为for)这里.


Edu*_*rdo 6

这是一个老问题,但我是R的新手并面临同样的问题.由于我的问题将被并行处理,我使用foreach并且看到与正常情况相比时的行为是不同的for:

library(foreach)

start_date = as.Date("2013-08-1")
end_date = as.Date("2013-08-13")
days = seq(start_date, end_date, by = "day")

foreach(day = days, .combine='rbind') %dopar% {
  print(class(day))
}

[1] "Date"
[1] "Date"
[1] "Date"
[1] "Date"
...
Run Code Online (Sandbox Code Playgroud)

由于我对大多数R的内在事物没有经验,因此我不知道为什么foreach最终会有不同的行为,但这对我的目的有用,并且希望可能对其他人有用.