Зацикливание на объекте datetime приводит к числовому итератору - PullRequest
42 голосов
/ 22 июня 2011

Почему повторение объекта 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"

Ответы [ 6 ]

33 голосов
/ 22 июня 2011

?"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
22 голосов
/ 24 июля 2012

цикл по дням (строки):

     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])
      }
18 голосов
/ 22 августа 2011

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

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

6 голосов
/ 31 июля 2014

Это старый вопрос, но я новичок в 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 голосов
/ 24 апреля 2014

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

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

1 голос
/ 22 июня 2011

Любая числовая операция над объектами даты обычно возвращает количество дней.В этом вы просите предоставить вам количество дней от эпохи.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 ) )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...