Подтвердить что ты не робот

Зацикливание объекта datetime приводит к числовому итератору

Почему выполняется повторение с помощью объекта 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"
4b9b3361

Ответ 1

?"for" говорит, что seq (часть после in) является выражением "[A] n, оценивающим вектор (включая список и выражение) или парный список или" NULL ".

Таким образом, ваш вектор Date принуждается к numeric, потому что Date объекты не являются строго векторами:

is.vector(Sys.Date())
# [1] FALSE
is.vector(as.numeric(Sys.Date()))
# [1] TRUE

То же самое верно для векторов POSIXct:

is.vector(Sys.time())
# [1] FALSE
is.vector(as.numeric(Sys.time()))
# [1] TRUE

Ответ 2

цикл через дни (строки):

     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])
      }

Ответ 3

Вы не выбираете правильную функцию для применения к векторам Date при использовании for-loops. Лучше было бы обернуть seq_along для почти каждой даты или фактора, который зацикливается. Затем вы сделаете две вещи: a) настройте ее так, чтобы вы ожидали индекс, начинающийся с 1, и b) защищайте от странных вещей, которые происходят с векторами нулевой длины. Я также думаю, что было бы лучше использовать его с факторами, которые for-loops превратятся в символьные векторы.

Что касается ответа Джошуа (что, безусловно, правильно и полезно), я думаю, что функция is.vector немного неверно маркирована или может быть просто неправильно понята. Его можно было бы более точно назвать hasNoAttributesOtherThanName. Свойство, которое большинство людей считают "векторным", тестируется с объектами is.atomic и Date и POSIXct, возвращает TRUE из этого теста.

Ответ 4

Кажется, что функция C, которая реализует цикл for, не копирует никаких векторных атрибутов. Это также включает атрибут class, который должен сделать i как объект Date.

Вы можете изучить исходный код функции do_for(SEXP, SEXP, SEXP, SEXP) (тот, который вызывается R for) здесь.

Ответ 5

Это старый вопрос, но я новичок в 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"
...

Поскольку я не испытываю внутренних вещей большинства R, поэтому я не знаю, почему foreach заканчивается тем, что имеет другое поведение, но это сработало для моей цели и, надеюсь, может быть полезно для кого-то другого.

Ответ 6

Любая числовая операция на объектах даты обычно возвращает количество дней. В этом вы просите его предоставить вам количество дней с эпохи. 14245, который представляет собой количество дней между 1970-01-01 - 2009-01-01

От? Даты:

Даты представлены как число дней с 1970-01-01, с отрицательными значения для более ранних дат. Они есть всегда печатаются по правилам текущий григорианский календарь, даже хотя этот календарь не использовался давно (он был принят в 1752 году в Великобритания и ее колонии).

Предполагается, что дата должна быть целое число, но это не применяется во внутреннем представлении. Дробные дни будут проигнорированы, если печать. Можно производить дробные дни через средний метод или путем добавления или вычитания (см. Ops.Date).

Попробуйте добавить print(day), чтобы понять, что я имею в виду.

test = as.Date("2009-01-01")
print( class( test ) )
for ( day in test )
{
  print(day)
  print( class( day ) )
}