Конвертировать UT C Время в Местное время с переменными часовыми поясами в R - PullRequest
1 голос
/ 28 февраля 2020

У меня есть фрейм данных с одним столбцом, содержащим POSIXct отметки времени, все из которых находятся в UT C времени, и другой столбец, содержащий часовые пояса, например:

time_data
   time_stamp        time_zone       
   <dttm>              <chr>           
 1 2020-02-06 07:08:59 America/Chicago 
 2 2020-02-06 07:43:50 America/Denver  
 3 2020-02-06 08:44:51 America/New_York
 4 2020-02-06 08:45:07 America/New_York
 5 2020-02-06 08:45:10 America/New_York
 6 2020-02-06 08:45:14 America/New_York
 7 2020-02-06 08:45:30 America/New_York
 8 2020-02-06 08:45:47 America/Chicago 
 9 2020-02-06 08:45:48 America/New_York
10 2020-02-06 08:45:49 America/New_York

Я знаю, что Я могу использовать функцию lubridate::with_tz для преобразования отдельной метки времени UT C POSIXct во временную метку, локализованную в часовом поясе, например:

with_tz(time_data$time_stamp[1], tz=time_data$time_zone[1])
"2020-02-06 01:08:59 CST"

Однако я пытаюсь сделать это для весь вектор / столбец, я получаю сообщение об ошибке:

with_tz(time_data$time_stamp, tz=time_data$time_zone)
Error in as.POSIXlt.POSIXct(x, tz) : invalid 'tz' value

Любые советы будут высоко оценены! Спасибо!

1 Ответ

0 голосов
/ 01 марта 2020

Вы можете выполнить эту задачу, но у вас останутся списки в новом столбце. Когда у вас есть несколько часовых поясов, вы должны работать немного больше, чем обычно. Что вам нужно, это go через каждый часовой пояс и часовой пояс и создать новую временную метку. Ваш образец данных называется mydf. В следующем коде я сначала создал объект даты, поскольку time_stemp в символе в mydf. Затем для каждой строки возьмите время и часовой пояс и используйте with_tz(). map2() справляется с работой. Вы можете использовать mapply() тоже. Поскольку map2() возвращает списки, в конце я использовал unnest().

library(tidyverse)
library(lubridate)

mutate(mydf, time_stamp = as.POSIXct(time_stamp, format = "%Y-%m-%d %H:%M:%S", tz = "UTC"),
       new_time = map2(.x = time_stamp, .y = time_zone, 
                       .f = function(x, y) {with_tz(time = x, tzone = y)})) 


Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   10 obs. of  3 variables:
 $ time_stamp: POSIXct, format: "2020-02-06 07:08:59" "2020-02-06 07:43:50" "2020-02-06 08:44:51" "2020-02-06 08:45:07" ...
 $ time_zone : chr  "America/Chicago" "America/Denver" "America/New_York" "America/New_York" ...
 $ new_time  :List of 10
  ..$ : POSIXct, format: "2020-02-06 01:08:59"
  ..$ : POSIXct, format: "2020-02-06 00:43:50"
  ..$ : POSIXct, format: "2020-02-06 03:44:51"
  ..$ : POSIXct, format: "2020-02-06 03:45:07"
  ..$ : POSIXct, format: "2020-02-06 03:45:10"
  ..$ : POSIXct, format: "2020-02-06 03:45:14"
  ..$ : POSIXct, format: "2020-02-06 03:45:30"
  ..$ : POSIXct, format: "2020-02-06 02:45:47"
  ..$ : POSIXct, format: "2020-02-06 03:45:48"
  ..$ : POSIXct, format: "2020-02-06 03:45:49"

Если вы не возражаете, чтобы даты были символами, вы можете сделать следующее.

mutate(mydf, time_stamp = as.POSIXct(time_stamp, format = "%Y-%m-%d %H:%M:%S", tz = "UTC"),
       new_time = map2(.x = time_stamp, .y = time_zone, 
                   .f = function(x, y) {as.character(with_tz(time = x, tzone = y))})) %>% 
unnest(new_time)

   time_stamp          time_zone        new_time           
   <dttm>              <chr>            <chr>              
 1 2020-02-06 07:08:59 America/Chicago  2020-02-06 01:08:59
 2 2020-02-06 07:43:50 America/Denver   2020-02-06 00:43:50
 3 2020-02-06 08:44:51 America/New_York 2020-02-06 03:44:51
 4 2020-02-06 08:45:07 America/New_York 2020-02-06 03:45:07
 5 2020-02-06 08:45:10 America/New_York 2020-02-06 03:45:10
 6 2020-02-06 08:45:14 America/New_York 2020-02-06 03:45:14
 7 2020-02-06 08:45:30 America/New_York 2020-02-06 03:45:30
 8 2020-02-06 08:45:47 America/Chicago  2020-02-06 02:45:47
 9 2020-02-06 08:45:48 America/New_York 2020-02-06 03:45:48
10 2020-02-06 08:45:49 America/New_York 2020-02-06 03:45:49

ДАННЫЕ

mydf <- structure(list(time_stamp = c("2020-02-06 07:08:59", "2020-02-06 07:43:50", 
"2020-02-06 08:44:51", "2020-02-06 08:45:07", "2020-02-06 08:45:10", 
"2020-02-06 08:45:14", "2020-02-06 08:45:30", "2020-02-06 08:45:47", 
"2020-02-06 08:45:48", "2020-02-06 08:45:49"), time_zone = c("America/Chicago", 
"America/Denver", "America/New_York", "America/New_York", "America/New_York", 
"America/New_York", "America/New_York", "America/Chicago", "America/New_York", 
"America/New_York")), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame"))
...