#r #date #dplyr #lubridate
#r #Дата #dplyr #lubridate
Вопрос:
Привет, у меня возникли некоторые проблемы с объектами даты и времени в R. У меня есть столбец, который на самом деле является просто столбцом времени, но когда он вводится в R, он считывается как вектор символов, но также со случайной датой. Моя первоначальная мысль, связанная с этой проблемой, заключалась в том, чтобы сначала преобразовать этот столбец time в объект datetime, используя lubridate::mdy_hms()
, а затем извлекая только время, используя strftime()
или srtptime()
, но, насколько я понимаю, это strptime()
применимо только к символьным векторам, тогда strftime()
как применяется к значениям POSIXct. Я использую mdy_hms()
функцию для преобразования поля в объект POSIXct, а затем пытаюсь извлечь только время использования strftime()
, но на самом деле это не работает. Я получаю эту ошибку:
Error in as.POSIXlt.default(x, tz = tz) :
do not know how to convert 'x' to class “POSIXlt”
Я попробовал это снова, но с помощью hms
пакета, однако он не распознает полные значения в моем векторе времени и преобразует все в NA
значения. Вот почему я подумал сначала преобразовать все значения в этом символьном векторе в значения даты и времени, а затем «выбросить» значение даты, поскольку оно неверно. Это код, который я пытаюсь запустить:
library(tidyverse)
library(lubridate)
library(hms)
OM <- read_csv('OM_sightings-1948-2019.csv', na = c("", "NA", "<Null>")) %>%
#Rename the ID column to OM_ID --> indicates that this entry came from OM database
rename(OM_ID = ID, Time = Time1, OM_Source = Source) %>%
# Drop the Time2, column
select(-Time2) %>%
# Convert 0.0 to NA in both the ActLat and ActLong columns
mutate_at(vars(ActLat, ActLong), na_if, y = 0)
#Fix the date and time objects in the db
OM_time <- OM %>%
mutate(Time = as_hms(Time),
SightDate = as.Date(mdy_hms(SightDate), tz = "US/Pacific"),
SightDateTime = mdy_hms(paste(SightDate, Time1), tz = "US/Pacific"))
Он работает нормально, и я вижу свой «мутированный» df, однако я получаю эти предупреждающие сообщения, которые я понимаю (в основном), но не уверен, как устранить неполадки:
Warning messages:
1: Problem with `mutate()` input `Time`.
ℹ Lossy cast from <character> to <hms> at position(s) 58, 60, 61, 62, 63, ... (and 102131 more)
ℹ Input `Time` is `as_hms(Time)`.
2: Lossy cast from <character> to <hms> at position(s) 58, 60, 61, 62, 63, ... (and 102131 more)
3: Problem with `mutate()` input `SightDateTime`.
ℹ All formats failed to parse. No formats found.
ℹ Input `SightDateTime` is `mdy_hm(SightDate, tz = "US/Pacific") Time`.
4: All formats failed to parse. No formats found.
Это примерное подмножество моих данных:
structure(list(OM_ID = c(94079, 75473, 95592, 50725, 24689, 73538,
10246, 107438, 10129, 74301, 107371, 63757, 43427, 93087, 16374,
28869, 38644, 42348, 89933, 83809, 53855, 96622, 52702, 28263,
991), SightDate = c("4/22/2015 0:00:00", "7/15/2011 0:00:00",
"6/30/2015 0:00:00", "6/26/2007 0:00:00", "8/12/2000 0:00:00",
"6/11/2011 0:00:00", "6/28/1990 0:00:00", "12/7/2018 0:00:00",
"6/20/1990 0:00:00", "6/26/2011 0:00:00", "12/5/2018 0:00:00",
"9/1/2009 0:00:00", "8/27/2005 0:00:00", "11/14/2014 0:00:00",
"6/11/1997 0:00:00", "9/10/2001 0:00:00", "9/8/2004 0:00:00",
"7/18/2005 0:00:00", "6/25/2014 0:00:00", "8/6/2012 0:00:00",
"5/16/2008 0:00:00", "7/25/2015 0:00:00", "9/10/2007 0:00:00",
"8/16/2001 0:00:00", "1/6/1977 0:00:00"), Time = c("12/30/1899 14:00:00",
"12/30/1899 15:00:00", "12/30/1899 19:21:00", "12/30/1899 9:30:00",
"12/30/1899 9:30:00", "12/30/1899 12:00:00", "12/30/1899 18:30:00",
"12/30/1899 13:00:00", "12/30/1899 18:00:00", "12/30/1899 11:52:00",
"12/30/1899 9:15:00", "12/30/1899 15:33:00", "12/30/1899 9:00:00",
"12/30/1899 13:48:00", "12/30/1899 15:00:00", "12/30/1899 5:45:00",
NA, "12/30/1899 16:15:00", "12/30/1899 12:30:00", NA, "12/30/1899 12:00:00",
"12/30/1899 13:00:00", "12/30/1899 12:30:00", "12/30/1899 8:45:00",
"12/30/1899 14:15:00"), Month = c(4, 7, 6, 6, 8, 6, 6, 12, 6,
6, 12, 9, 8, 11, 6, 9, 9, 7, 6, 8, 5, 7, 9, 8, 1), Day = c(22,
15, 30, 26, 12, 11, 28, 7, 20, 26, 5, 1, 27, 14, 11, 10, 8, 18,
25, 6, 16, 25, 10, 16, 6), Year = c(2015, 2011, 2015, 2007, 2000,
2011, 1990, 2018, 1990, 2011, 2018, 2009, 2005, 2014, 1997, 2001,
2004, 2005, 2014, 2012, 2008, 2015, 2007, 2001, 1977), Pod = c("Orcas",
"JpLp", "JK", "Orcas", "L", "J", "Orcas", "J", "J", "JK", "J",
"L12s", "Orcas", "J", "Orcas", "Orcas", "JKL", "J", "J", "J",
"J", "JKL", "JL", "JL", "Orcas"), LikelyPod = c("Ts", "JKLp",
"JpKp", NA, NA, "JL53", NA, NA, NA, "JpKp", NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, "SRs"), Direction = c(NA,
"mill", NA, NA, "E", "SE", "N", "N", "W", NA, "N", "NW", "N",
NA, "N", NA, "N", "N", "N", "N", "N", "SW", NA, "N", "N"), FishArea = c("17C",
"7", "7", "7", "19C", "7", "7", "9", "18C", "18C", "11", "7",
"7", "9", "7", "7", "7", "18C", "7", "7", "18C", "18", "29",
"7", "10"), Quadrant = c(89, 184, 181, 184, 257, 181, 185, 397,
151, 152, 420, 185, 181, 387, 169, 181, 181, 162, 176, 170, 163,
151, 80, 176, 413), Lat = c(48.96, 48.46, 48.5, 48.46, 48.31,
48.5, 48.44, 47.9, 48.76, 48.74, 47.33, 48.44, 48.5, 48.12, 48.62,
48.5, 48.5, 48.74, 48.56, 48.65, 48.71, 48.76, 49.01, 48.56,
47.55), Long = c(-123.73, -123.1, -123.17, -123.1, -123.36, -123.17,
-123.03, -122.46, -123.02, -123.08, -122.44, -123.03, -123.17,
-122.71, -123.17, -123.17, -123.17, -123.3, -123.21, -123.24,
-123.26, -123.02, -123.16, -123.21, -122.41), UTMx = c(446800,
492000, 487000, 492000, 473400, 487000, 497400, 539100, 497800,
493500, 540300, 497400, 487000, 520500, 486900, 487000, 487000,
477600, 484200, 482300, 480700, 497800, 488100, 484200, 542200
), UTMy = c(5423900, 5367800, 5372600, 5367800, 5351700, 5372600,
5365800, 5305200, 5401200, 5399200, 5242800, 5365800, 5372600,
5329700, 5386000, 5372600, 5372600, 5399000, 5378600, 5389300,
5395300, 5401200, 5428700, 5378600, 5266600), OM_Source = c("TWM-SA-Pub",
"TWM-SW", "TWM-HYD-Rel", "TWM-Pager", "TWM-Pager", "TWM-SW",
"TWM-SA-Rel", "TWM-SA-Rel", "TWM-SA-Rel", "SPOT", "TWM-SA-Pub",
"SPOT", "TWM-Pager", "TWM-HYD-Rel", "TWM-Pager", "TWM-SA-Pub",
"TWM-SA-Rel", "TWM-Pager", "TWM-SW", "BCCSN", "TWM-SW", "Soundwatch",
"BCCSN", "TWM-Pager", "TWM-SA-Rel"), ActLat = c(NA, 48.452, NA,
NA, NA, 48.488, NA, NA, NA, 48.7667, NA, 48.4585, NA, NA, NA,
NA, NA, NA, 48.5385, 48.682, 48.738, 48.7876, 49.0108, NA, NA
), ActLong = c(NA, -123.0777, NA, NA, NA, -123.1233, NA, NA,
NA, -123.0776, NA, -123.065, NA, NA, NA, NA, NA, NA, -123.1725,
-123.251, -123.253, -123.0389, -123.1659, NA, NA)), row.names = c(NA,
-25L), class = c("tbl_df", "tbl", "data.frame"))
Я ценю любую помощь! Я довольно новичок / самоучка, и мне трудно понять, как лучше всего работать с данными о времени в целом.
Комментарии:
1. Это сводится к тому, что представляют времена. Если это времена суток, вам лучше всего сохранить их как даты и времени и печатать только временную часть. Если это длительности, вы можете либо сохранить их как целые числа секунд или минут, либо использовать что-то вроде
duration
from lubridate .2. Вы поделились своими данными после некоторой обработки, которую вы обсуждали, и со столбцом «tz». Возможно, было бы более полезно опубликовать примерные данные с более раннего этапа процесса, прежде чем вообще преобразовывать время.
3. Извините, я этого не понял! Я только что обновил
dput()
свое подмножество. Пожалуйста, дайте мне знать, если это работает нормально!4. @AllanCameron извините за неясность, я пытаюсь сохранить эти данные как объект времени суток. Не длительность. Честно говоря, я действительно раздражен тем, как были импортированы эти данные, потому что в исходной базе данных в столбце time нет даты, и я думаю, что это искусственный экспорт и импорт на разных платформах.
Ответ №1:
Даты и время могут быть довольно сложными в R, поскольку существует так много разных способов их представления. lubridate
не имеет класса, который является просто time, но связанный пакет hms
добавляет класс time, который может упростить задачу.
Я часто считаю полезным иметь столбцы даты и даты / времени, чтобы вы могли использовать ту часть, которая имеет наибольший смысл.
Для примера данных, используя lubridate::mdy_hms(SighDate), он преобразуется в дату в полночь. hms::as_hms(Time)
сработало для меня. Затем добавьте два для создания в столбце date_time, затем преобразуйте дату в класс date, если вам это нужно для анализа. Ниже я создал новый столбец для time, чтобы отслеживать, что он делает, но, как правило, заменяет столбец time.
library(lubridate)
library(hms)
library(tidyverse)
# OM = your data provided above
OM2 <- OM %>%
mutate(SightDate = mdy_hms(SightDate, tz = "America/Los_Angeles"),
Time2 = as_hms(mdy_hms(Time)),
Date_time = SightDate Time2,
SightDate = as.Date(SightDate)
)
OM2 %>%
select(OM_ID, SightDate, Time, Time2, Date_time, everything())
# # A tibble: 25 x 20
# OM_ID SightDate Time Time2 Date_time Month Day Year Pod LikelyPod Direction FishArea Quadrant Lat
# <dbl> <date> <chr> <tim> <dttm> <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <dbl> <dbl>
# 1 94079 2015-04-22 12/3~ 14:00 2015-04-22 14:00:00 4 22 2015 Orcas Ts NA 17C 89 49.0
# 2 75473 2011-07-15 12/3~ 15:00 2011-07-15 15:00:00 7 15 2011 JpLp JKLp mill 7 184 48.5
# 3 95592 2015-06-30 12/3~ 19:21 2015-06-30 19:21:00 6 30 2015 JK JpKp NA 7 181 48.5
# 4 50725 2007-06-26 12/3~ 09:30 2007-06-26 09:30:00 6 26 2007 Orcas NA NA 7 184 48.5
# 5 24689 2000-08-12 12/3~ 09:30 2000-08-12 09:30:00 8 12 2000 L NA E 19C 257 48.3
# 6 73538 2011-06-11 12/3~ 12:00 2011-06-11 12:00:00 6 11 2011 J JL53 SE 7 181 48.5
# 7 10246 1990-06-28 12/3~ 18:30 1990-06-28 18:30:00 6 28 1990 Orcas NA N 7 185 48.4
# 8 107438 2018-12-07 12/3~ 13:00 2018-12-07 13:00:00 12 7 2018 J NA N 9 397 47.9
# 9 10129 1990-06-20 12/3~ 18:00 1990-06-20 18:00:00 6 20 1990 J NA W 18C 151 48.8
# 10 74301 2011-06-26 12/3~ 11:52 2011-06-26 11:52:00 6 26 2011 JK JpKp NA 18C 152 48.7
# # ... with 15 more rows, and 6 more variables: Long <dbl>, UTMx <dbl>, UTMy <dbl>, OM_Source <chr>, ActLat <dbl>,
# # ActLong <dbl>
Я почти уверен, что Access представляет даты и время в виде числовых значений, представляющих количество времени с момента некоторого происхождения. Похоже, что используется исходное значение 12/30/1899, которое отображается в вашем столбце времени. Вы также можете просмотреть свои настройки при экспорте из Access в csv. Я больше знаком с Excel, но думаю, что они настроили его аналогично, чтобы вы могли манипулировать форматом перед импортом.
Комментарии:
1. Спасибо! Так что да, я не хотел давать слишком много подробностей, опасаясь запутать мой пост, но да. У меня есть столбец даты с истинной датой, а столбец времени (в Access) отображает время только в 24-часовом формате. Однако при импорте в R он добавляет случайную дату. Использование
hms::as_hms
вызова делает то, чего я боялся, и удаляет все содержимое вектора времени и вместо этого заполняет его значениями NA. Я обновлю свой OP, чтобы отразить лучший вопрос, код и образцы данных. Большое спасибо за вашу помощь!2. Я обновил новые данные образца. Использование предоставленного вами примера as_hms работало нормально, но если он возвращает NA, это может быть вызвано чем-то за пределами опубликованного вами подмножества.
3. Я думаю, что ваши ошибки возникают из-за использования as_hms для данных, которые имеют компонент даты, а также компонент времени. Вы можете либо сначала преобразовать в POSIXct с помощью mdy_hms(), либо удалить бессмысленный компонент даты перед преобразованием символа во время.
4. Да! Это сработало, спасибо! Однако, когда у меня есть
NA
значения времени, они по-прежнему заполняются в столбце SightDateTime, т.е. (1/1/2010 NA), но я надеялся, что если для time было NA, оно не будет добавлено к SightDateTime. Я также по-прежнему получаю столбец «tz», добавленный в конец моего df, тогда как в прошлом этого не происходило, и я не уверен, почему? Это код, который я в итоге запустил:OM_time <- OM %>% mutate(Time = as_hms(mdy_hms(Time)), SightDate = as.Date(mdy_hms(SightDate), tz = "US/Pacific"), SightDateTime = paste(SightDate, Time), tz = "US/Pacific")
5. Вы создаете столбец tz в приведенном выше коде, я думаю, он должен быть внутри круглых скобок для mdy_hms.