Проблема с часовыми поясами в фрейме данных и данных POSIXct

У меня есть несколько дат с разными часовыми поясами - я могу создать фрейм данных с разными столбцами. Это выглядит примерно так:

timedate <- c("2024-03-31T03:14:00", "2024-03-24T01:07:00", "2024-04-09T22:45:00")
zones <- c("UTC", "Australia/Brisbane", "Australia/Canberra")
df <- tibble(timedate, zones)
df
> A tibble: 3 × 2
> timedate            zones             
>   <chr>               <chr>             
> 1 2024-03-31T03:14:00 UTC               
> 2 2024-03-24T01:07:00 Australia/Brisbane
> 3 2024-04-09T22:45:00 Australia/Canberra

Я знаю, что для создания столбца данных класса POSIX работает следующее...

df <- mutate(df
        ,timedatezone = as.POSIXct(timedate,format = "%Y-%m-%dT%H:%M", tz = 'UTC'))
df
> A tibble: 3 × 3
> timedate            zones              timedatezone       
>   <chr>               <chr>              <dttm>             
> 1 2024-03-31T03:14:00 UTC                2024-03-31 03:14:00
> 2 2024-03-24T01:07:00 Australia/Brisbane 2024-03-24 01:07:00
> 3 2024-04-09T22:45:00 Australia/Canberra 2024-04-09 22:45:00

но... следующее не

df <- mutate(df
        ,timedatezone = as.POSIXct(timedate,format = "%Y-%m-%dT%H:%M", tz = zones))

> Error in `mutate()`:
> In argument: `timedatezone = as.POSIXct(timedate, format = "%Y-%m-%dT%H:%M", tz = zones)`.
> Caused by error in `strptime()`:
> invalid 'tz' value
> Run `rlang::last_trace()` to see where the error occurred.

Я чувствую, что мне не хватает чего-то очень простого, но я гуглил и гуглил и не могу найти решение.

В конечном счете, мне нужен столбец со значениями, которые знают, в каком часовом поясе они находятся, или столбец, в котором все значения будут находиться в одном часовом поясе (где я знаю, что это за часовой пояс).

Вы не можете иметь несколько часовых поясов для одного вектора POSIXct. Лучшее, что вы можете сделать, это составить список, например: Map(as.POSIXct, df$timedate, format = "%Y-%m-%dT%H:%M", tz=df$zones)

thelatemail 19.06.2024 03:39

ох, я этого не осознавал. Я думал, что у каждого элемента вектора может быть свой часовой пояс.

fake fake 19.06.2024 05:19

в конечном итоге мне нужен столбец с постоянным часовым поясом.

fake fake 19.06.2024 06:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Возможно, это поможет, если вам нужен один консолидированный столбец даты и времени (в формате UTC):

df |>
  rowwise() |>
  mutate(timedatezone = as.POSIXct(timedate, format = "%Y-%m-%dT%H:%M", tz = zones)) |>
  ungroup()

Результат

# A tibble: 3 × 3
  timedate            zones              timedatezone       
  <chr>               <chr>              <dttm>             
1 2024-03-31T03:14:00 UTC                2024-03-31 03:14:00
2 2024-03-24T01:07:00 Australia/Brisbane 2024-03-23 15:07:00
3 2024-04-09T22:45:00 Australia/Canberra 2024-04-09 12:45:00

это звучит как лучший вариант. У меня есть несколько строк «NA», и это, похоже, вызывает трудности. Это должно сработать, как только я найду исправление для строк NA.

fake fake 19.06.2024 05:38

Будьте осторожны: кажется, что для вывода из первой строки data.frame/tibble используется часовой пояс, и он будет меняться незаметно, без предупреждения о том, что имело место это приведение.

thelatemail 19.06.2024 06:03

я отфильтровал все строки NA, но, похоже, я не уверен, что означает следующее > df$timedatezone NULL Предупреждающее сообщение: Неизвестный или неинициализированный столбец: timedatezone.

fake fake 19.06.2024 06:13

Чтобы объединить все времена в один часовой пояс, используйте as.POSIXct() в mapply(), предоставляя время, пояса и форматы в виде векторов поэлементно. Первоначально преобразованный в "POSIXct", он возвращает числовое значение (секунды с 1 января 1970 г.). Примените as.POSIXct() еще раз, установив целевой часовой пояс, например "UTC".

> f <- \(x, tz, format = "%FT%T", new.tz = "UTC") {
+   xtz <-  mapply(as.POSIXct, x, format=format, tz=tz)
+   as.POSIXct(xtz, tz=new.tz)
+ }
> with(df, f(x=timedate, tz=zones))  ## 'UTC', default
      2024-03-31T03:14:00       2024-03-24T01:07:00       2024-04-09T22:45:00 
"2024-03-31 03:14:00 UTC" "2024-03-23 15:07:00 UTC" "2024-04-09 12:45:00 UTC" 
> with(df, f(x=timedate, tz=zones, new.tz='America/Los_Angeles'))
      2024-03-31T03:14:00       2024-03-24T01:07:00       2024-04-09T22:45:00 
"2024-03-30 20:14:00 PDT" "2024-03-23 08:07:00 PDT" "2024-04-09 05:45:00 PDT" 
> df |> transform(tdz=f(x=timedate, zones, 'America/Los_Angeles'))
                               timedate              zones                 tdz
2024-03-31T03:14:00 2024-03-31T03:14:00                UTC 2024-03-30 20:14:00
2024-03-24T01:07:00 2024-03-24T01:07:00 Australia/Brisbane 2024-03-23 08:07:00
2024-04-09T22:45:00 2024-04-09T22:45:00 Australia/Canberra 2024-04-09 05:45:00

Примечание. Класс "POSIXct" на самом деле представляет собой числовой вектор с атрибутом "tzone" для указания часового пояса.


Данные:

> dput(df)
structure(list(timedate = c("2024-03-31T03:14:00", "2024-03-24T01:07:00", 
"2024-04-09T22:45:00"), zones = c("UTC", "Australia/Brisbane", 
"Australia/Canberra")), class = "data.frame", row.names = c(NA, 
-3L))

не могли бы вы рассказать об этом немного подробнее для моей пользы? Я не знаком с таким способом создания функции? На самом деле я не могу следить за тем, что вы сделали. Заранее спасибо за вашу помощь

fake fake 19.06.2024 07:28

@fakefake Можно поконкретнее, пожалуйста?

jay.sf 19.06.2024 07:30

Я не понимаю первую строку, начинающуюся с "f <-". Мне показалось, что вы создаете функцию, но это было за пределами уровня функций, которые я создавал в прошлом.

fake fake 26.06.2024 05:36

@fakefake \(x) — это просто псевдоним для function(x), вы также можете использовать последний в текущей версии R.

jay.sf 26.06.2024 05:42

Я думаю, это можно немного упростить - кажется, я получаю те же результаты, не используя часть attr<-: f <- function(x, tz, format = "%FT%T", new.tz = "UTC") {xtz <- mapply(as.POSIXct, x, format=format, tz=tz); as.POSIXct(xtz, tz=new.tz)}

thelatemail 11.07.2024 05:23

@thelatemail Вы правы, числовой атрибут был избыточным. Фактическую работу делает второй as.POSIXct(<NUM>, tz=new.tz).

jay.sf 11.07.2024 06:41
Ответ принят как подходящий

Я предлагаю вам использовать пакет datetimeoffset.

df <- data.frame(timedate = c("2024-03-31T03:14:00", "2024-03-24T01:07:00", "2024-04-09T22:45:00"), 
                 zones = c("UTC", "Australia/Brisbane", "Australia/Canberra"))

library(datetimeoffset)
df$parsed <- as_datetimeoffset(df$timedate, tz = df$zones) |> as.POSIXct(tz = "UTC")
df
#             timedate              zones              parsed
#1 2024-03-31T03:14:00                UTC 2024-03-31 03:14:00
#2 2024-03-24T01:07:00 Australia/Brisbane 2024-03-23 15:07:00
#3 2024-04-09T22:45:00 Australia/Canberra 2024-04-09 12:45:00

Что ж, это сработало. Спасибо.

fake fake 27.06.2024 06:17

Другие вопросы по теме