Даты, импортированные из Excel в R, дают разные результаты, если по-разному конвертировать их в символы - PullRequest
0 голосов
/ 11 мая 2018

Импорт таблицы Excel, содержащей даты, в R (с использованием readxl). Например.

`# A tibble: 9 x 2
     id       date
  <dbl>     <dttm>
1     1 2000-01-23
2     2 2000-01-24
3     3 2000-01-25
4     4 2000-01-26
5     5 2000-01-27
6     6 2000-01-28
7     7 2000-01-29
8     8 2000-01-30
9     9 2000-01-31`

Теперь преобразуйте столбец даты в символы:

  1. Используйте $

> as.character(dat$date) [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27" "2000-01-28" "2000-01-29" "2000-01-30" "2000-01-31"

  1. Использовать [[]]

> as.character(dat[[2]]) [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27" "2000-01-28" "2000-01-29" "2000-01-30" "2000-01-31"

  1. Использовать [,]

> as.character(dat[ , 2]) [1] "c(948585600, 948672000, 948758400, 948844800, 948931200, 949017600, 949104000, 949190400, 949276800)"

Почему третий случай дает разные результаты? Я полагаю, что первые 2 случая возвращают векторы, а третий случай возвращает фрейм данных, но почему это имеет значение? И откуда взялись цифры в случае 3? (Эти цифры не соответствуют числам, используемым в Excel для представления дат.)

1 Ответ

0 голосов
/ 11 мая 2018

Разница в том, что у вас есть tibble, а не data.frame. data.frame по умолчанию будет уменьшаться до вектора, если поднабор возвратит один столбец или одну строку; Вы можете использовать drop=F (см. ниже), чтобы предотвратить это.

Это считается "хорошей функцией" в пакетах на основе tidyverse: делать одно, всегда возвращать один и тот же класс / структуру и т. Д. Функции, которые возвращают list или vector таким образом, чтобы программно, возможно, не было предсказано, может считаться проблемой. (Из-за этого, когда я имею дело программно в необработанном data.frame тисках tbls, я часто добавляю ,drop=FALSE, когда мне нужно принять меры против него.)

На похожей ноте, вас когда-нибудь кусали sapply или mapply? Если возвращаемые значения имеют одинаковую длину / класс, то вы получите vector или matrix, но если какая-либо длина или класс не совпадают, вы получите list, ожидаете вы этого или нет , Это одно оправдание для «всегда», используя sapply(..., simplify=FALSE) или lapply(...) или mapply(..., SIMPLIFY=FALSE). Это также частичное оправдание для семейства функций purrr::map.

Примеры:

library(dplyr)
d1 <- data.frame(dt=seq.Date(as.Date('2000-01-23'),as.Date('2000-01-30'),by='day'))
d2 <- as.tbl(d1)

d1[,1]
# [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27"
# [6] "2000-01-28" "2000-01-29" "2000-01-30"
d2[,1]
# # A tibble: 8 × 1
#           dt
#       <date>
# 1 2000-01-23
# 2 2000-01-24
# 3 2000-01-25
# 4 2000-01-26
# 5 2000-01-27
# 6 2000-01-28
# 7 2000-01-29
# 8 2000-01-30

Почему это создает что-то необычное? Из-за чего-то еще у вас есть в данных.

d1$id <- 1:nrow(d1)
d2$id <- 1:nrow(d2)
as.character(d2)
# [1] "c(10979, 10980, 10981, 10982, 10983, 10984, 10985, 10986)"
# [2] "1:8"                                                      
as.character(d1[,1])
# [1] "2000-01-23" "2000-01-24" "2000-01-25" "2000-01-26" "2000-01-27"
# [6] "2000-01-28" "2000-01-29" "2000-01-30"
as.character(d1[,1,drop=FALSE])
# [1] "c(10979, 10980, 10981, 10982, 10983, 10984, 10985, 10986)"
as.character(d2[,1])
# [1] "c(10979, 10980, 10981, 10982, 10983, 10984, 10985, 10986)"

Когда вы вызываете функцию на весь кадр (независимо от того, tibble или нет), она часто преобразует все столбцы в формат с наименьшим общим значением, character < numeric < integer и POSIXt эффективно numeric (с информацией tz ), поэтому он приводится в numeric. так как в нем нет POSIXt. (Это в равной степени относится к POSIXt и Date классам.)

(Что касается фактических чисел, к которым их принуждают, я не знаю, не по назначению ...)

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