У меня есть несколько дат с разными часовыми поясами - я могу создать фрейм данных с разными столбцами. Это выглядит примерно так:
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.
Я чувствую, что мне не хватает чего-то очень простого, но я гуглил и гуглил и не могу найти решение.
В конечном счете, мне нужен столбец со значениями, которые знают, в каком часовом поясе они находятся, или столбец, в котором все значения будут находиться в одном часовом поясе (где я знаю, что это за часовой пояс).
ох, я этого не осознавал. Я думал, что у каждого элемента вектора может быть свой часовой пояс.
в конечном итоге мне нужен столбец с постоянным часовым поясом.





Возможно, это поможет, если вам нужен один консолидированный столбец даты и времени (в формате 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.
Будьте осторожны: кажется, что для вывода из первой строки data.frame/tibble используется часовой пояс, и он будет меняться незаметно, без предупреждения о том, что имело место это приведение.
я отфильтровал все строки NA, но, похоже, я не уверен, что означает следующее > df$timedatezone NULL Предупреждающее сообщение: Неизвестный или неинициализированный столбец: timedatezone.
Чтобы объединить все времена в один часовой пояс, используйте 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))
не могли бы вы рассказать об этом немного подробнее для моей пользы? Я не знаком с таким способом создания функции? На самом деле я не могу следить за тем, что вы сделали. Заранее спасибо за вашу помощь
@fakefake Можно поконкретнее, пожалуйста?
Я не понимаю первую строку, начинающуюся с "f <-". Мне показалось, что вы создаете функцию, но это было за пределами уровня функций, которые я создавал в прошлом.
@fakefake \(x) — это просто псевдоним для function(x), вы также можете использовать последний в текущей версии R.
Я думаю, это можно немного упростить - кажется, я получаю те же результаты, не используя часть 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 Вы правы, числовой атрибут был избыточным. Фактическую работу делает второй as.POSIXct(<NUM>, tz=new.tz).
Я предлагаю вам использовать пакет 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
Что ж, это сработало. Спасибо.
Вы не можете иметь несколько часовых поясов для одного вектора POSIXct. Лучшее, что вы можете сделать, это составить список, например:
Map(as.POSIXct, df$timedate, format = "%Y-%m-%dT%H:%M", tz=df$zones)