将多个时区转换成一个-r

时间:2019-04-01 20:10:23

标签: r time-series data-manipulation lubridate

我有这个数据框:

df <- data.frame(datetime = c("2018-08-23 11:03:25 0300", "2018-08-17 12:54:09 0300", "2018-08-07 17:15:29 0400", "2018-08-07 10:41:30 0400", "2018-08-07 10:37:37 0400", "2018-08-03 10:36:49 0400", "2018-07-26 12:52:28 0400", "2018-07-10 18:06:02 0400", "2018-07-04 17:52:24 0400", "2018-06-20 15:28:08 0400"),
           stringsAsFactors = FALSE)
> df
                       datetime
1  2018-08-23 11:03:25 0300
2  2018-08-17 12:54:09 0300
3  2018-08-07 17:15:29 0400
4  2018-08-07 10:41:30 0400
5  2018-08-07 10:37:37 0400
6  2018-08-03 10:36:49 0400
7  2018-07-26 12:52:28 0400
8  2018-07-10 18:06:02 0400
9  2018-07-04 17:52:24 0400
10 2018-06-20 15:28:08 0400

我需要在相同的时区中进行转换,并删除其时区(为什么?因为在相同类型的向量之间进行小时/天/周的计算会更容易)

预期输出:

              datetime
1  2018-08-23 12:03:25    # this was UTC +3, now +1 hour is UTC +4
2  2018-08-17 13:54:09    # this was UTC +3, now +1 hour is UTC +4
3  2018-08-07 17:15:29    # this is UTC +4
4  2018-08-07 10:41:30    # this is UTC +4
5  2018-08-07 10:37:37    # this is UTC +4
6  2018-08-03 10:36:49    # this is UTC +4
7  2018-07-26 12:52:28    # this is UTC +4
8  2018-07-10 18:06:02    # this is UTC +4
9  2018-07-04 17:52:24    # this is UTC +4
10 2018-06-20 15:28:08    # this is UTC +4

有什么想法吗?

编辑:

This问题是按位置的,它可以通过参数tz来解决,因为您可以在此处插入位置。但是,在这个问题中,我没有参数来识别字符串中的时区。

2 个答案:

答案 0 :(得分:2)

这有效,

使用library(tidyverse)library(stringr)

df <- data.frame(datetime = c("2018-08-23 11:03:25 0300", "2018-08-17 12:54:09 0300", "2018-08-07 17:15:29 0400", "2018-08-07 10:41:30 0400", "2018-08-07 10:37:37 0400", "2018-08-03 10:36:49 0400", "2018-07-26 12:52:28 0400", "2018-07-10 18:06:02 0400", "2018-07-04 17:52:24 0400", "2018-06-20 15:28:08 0400"),
                     stringsAsFactors = FALSE)

df2 <-  as.tibble(stringr::str_split_fixed(df$datetime, " ", 3)) %>% 
  mutate(V3 = -((as.numeric(V3)/100)-4)) %>% 
  mutate(V4 = as.numeric(stringr::str_split_fixed(V2, ":", 3)[,1]) + V3) %>% 
  mutate(V5 = stringr::str_split_fixed(.$V2, ":", 3)[,2]) %>% 
  mutate(V6 = stringr::str_split_fixed(.$V2, ":", 3)[,3]) %>% 
  mutate(V2 = paste(V4, V5, V6, sep = ":")) %>% 
  mutate(datetime = paste(V1, V2, sep = " ")) %>% 
  dplyr::select(datetime)

一些解释,首先我们将datetime列分为三部分,然后将timezone参数更改为可以添加的内容。 然后拆分时间和日期字符串,添加timezone参数,然后将其全部粘贴回去。可以用较少的行来完成此操作,但是您可以一次运行一个步骤来很好地遵循这些步骤。

答案 1 :(得分:2)

使用tidyverselubridate软件包的解决方案。

library(tidyverse)
library(lubridate)

df <- data.frame(datetime = c("2018-08-23 11:03:25 0300", "2018-08-17 12:54:09 0300", "2018-08-07 17:15:29 0400", "2018-08-07 10:41:30 0400", "2018-08-07 10:37:37 0400", "2018-08-03 10:36:49 0400", "2018-07-26 12:52:28 0400", "2018-07-10 18:06:02 0400", "2018-07-04 17:52:24 0400", "2018-06-20 15:28:08 0400"),
                 stringsAsFactors = FALSE)

df2 <- df %>%
  separate(datetime, into = c("date", "time", "timezone"), sep = " ") %>%
  unite(col = datetime, c("date", "time"), sep = " ") %>%
  mutate(datetime = ymd_hms(datetime)) %>%
  mutate(datetime = if_else(timezone %in% "0300", datetime + hours(1), datetime)) %>%
  select(-timezone)
df2
#               datetime
# 1  2018-08-23 12:03:25
# 2  2018-08-17 13:54:09
# 3  2018-08-07 17:15:29
# 4  2018-08-07 10:41:30
# 5  2018-08-07 10:37:37
# 6  2018-08-03 10:36:49
# 7  2018-07-26 12:52:28
# 8  2018-07-10 18:06:02
# 9  2018-07-04 17:52:24
# 10 2018-06-20 15:28:08