R: Что такое даты в векторе дат: даты или числовые значения?(разница между x [i] и i) - PullRequest
6 голосов
/ 17 мая 2019

Может кто-нибудь объяснить, почему в первом цикле каждый элемент моего вектора дат является датой, а во втором каждый элемент моего вектора дат числовой? Спасибо!

x <- as.Date(c("2018-01-01", "2018-01-02", "2018-01-02", "2018-05-06"))
class(x)
# Loop 1 - each element is a Date:
for (i in seq_along(x)) print(class(x[i]))
# Loop 2 - each element is numeric:
for (i in x) print(class(i))             

Ответы [ 3 ]

8 голосов
/ 18 мая 2019

Элементы Date, первый цикл правильный.

К сожалению, R не всегда имеет стиль второго цикла. Я считаю, что проблема заключается в том, что синтаксис for (i in x) обходит методы Date для методов доступа, таких как [, что он может сделать, потому что классы S3 в R очень тонкие и не мешают вам не использовать их намеченные интерфейсы. Это может сбивать с толку, потому что что-то вроде for (i in 1:4) print(i) работает напрямую, поскольку числовой тип является базовым вектором. Date - это S3, поэтому он приводится к числовому. Чтобы увидеть числовые объекты, которые печатаются во втором цикле, вы можете запустить это:

x <- as.Date(c("2018-01-01", "2018-01-02", "2018-01-02", "2018-05-06"))
for (i in x) print(i)
#> [1] 17532
#> [1] 17533
#> [1] 17533
#> [1] 17657

, который дает вам то же самое, что и неклассифицированная версия вектора Date. Эти числа являются днями с начала времени Unix, которые вы также можете увидеть ниже, если преобразовать их обратно в Date с этим origin.

unclass(x)
#> [1] 17532 17533 17533 17657
as.Date(unclass(x), "1970-01-01")
#> [1] "2018-01-01" "2018-01-02" "2018-01-02" "2018-05-06"

Так что я бы придерживался подходящих методов доступа для любых векторных типов S3, как вы делаете в первом цикле.

3 голосов
/ 18 мая 2019

Если вы посмотрите на ?'for', вы увидите, что for(var in seq) определяется только тогда, когда seq - это "выражение, вычисляющее вектор", а is.vector(x) - FALSE.Таким образом, документация говорит (может быть, не так ясно), что поведение здесь не определено, поэтому поведение является неожиданным.

Как упоминает Джоран, as.vector(x) возвращает числовой вектор, такой же как unclass(x), упомянутый Calum You.

3 голосов
/ 18 мая 2019

Когда вы запускаете:

for (i in seq_along(x)) print(class(x[i]))

Вы используете итератор i для каждого элемента x.Это означает, что каждый раз, когда вы получаете класс каждого повторяющегося члена x.

Однако, когда вы запускаете:

for (i in x) print(class(i))

Вы ищете класс каждого члена.Использование ?Date:

Даты представлены в виде количества дней с 1970-01-01

По этой причине вы получаете числовые значения в качестве класса.

Более того, если вы будете использовать print() для каждого цикла, вы получите даты и числа:

for (i in seq_along(x)) print(x[i])

[1] "2018-01-01"
[1] "2018-01-02"
[1] "2018-01-02"
[1] "2018-05-06"

и

for (i in x) print(i)

[1] 17532
[1] 17533
[1] 17533
[1] 17657

Наконец, если выЧтобы проверить логику R, мы можем сделать что-то вроде этого:

x[1] - as.Date("1970-01-01")

Взяв первый элемент x («2018-01-01») и вычтя «1970-01-01», который является первымДата.Наш вывод будет:

Time difference of 17532 days
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...