Как преобразовать столбец datetime из формата «не UTC» в формат «UTC» без потери данных дней, в которые происходит изменение времени в R - PullRequest
0 голосов
/ 07 апреля 2019

У меня есть фрейм данных df1 со столбцом datetime в формате UTC.Мне нужно объединить этот фрейм данных с фреймом данных df2 по столбцу datetime.Моя проблема в том, что df2 находится в формате Europe/Paris, и когда я преобразую df2$datetime из Europe/Paris в UTC формат, я теряю или дублирую данные в моменты, когда происходит изменение времени между летом или зимойили зима / лето.Например:

df1<- data.frame(datetime=c("2016-10-29 22:00:00","2016-10-29 23:00:00","2016-10-30 00:00:00","2016-10-30 01:00:00","2016-10-30 02:00:00","2016-10-30 03:00:00","2016-10-30 04:00:00","2016-10-30 05:00:00","2016-03-25 22:00:00","2016-03-25 23:00:00","2016-03-26 00:00:00","2016-03-26 01:00:00","2016-03-26 02:00:00","2016-03-26 03:00:00","2016-03-26 04:00:00"), Var1= c(4, 56, 76, 54, 34, 3, 4, 6, 78, 23, 12, 3, 5, 6, 7))
df1$datetime<- as.POSIXct(df1$datetime, format = "%Y-%m-%d %H", tz= "UTC")
df2<- data.frame(datetime=c("2016-10-29 22:00:00","2016-10-29 23:00:00","2016-10-30 00:00:00","2016-10-30 01:00:00","2016-10-30 02:00:00","2016-10-30 03:00:00","2016-10-30 04:00:00","2016-10-30 05:00:00","2016-03-25 22:00:00","2016-03-25 23:00:00","2016-03-26 00:00:00","2016-03-26 01:00:00","2016-03-26 02:00:00","2016-03-26 03:00:00","2016-03-26 04:00:00"), Var2=c(56, 43, 23, 14, 51, 27, 89, 76, 56, 4, 35, 23, 4, 62, 84))
df2$datetime<- as.POSIXct(df2$datetime, format = "%Y-%m-%d %H", tz= "Europe/Paris")

df1
              datetime Var1
1  2016-10-29 22:00:00    4
2  2016-10-29 23:00:00   56
3  2016-10-30 00:00:00   76
4  2016-10-30 01:00:00   54
5  2016-10-30 02:00:00   34
6  2016-10-30 03:00:00    3
7  2016-10-30 04:00:00    4
8  2016-10-30 05:00:00    6
9  2017-03-25 22:00:00   78
10 2017-03-25 23:00:00   23
11 2017-03-26 00:00:00   12
12 2017-03-26 01:00:00    3
13 2017-03-26 02:00:00    5
14 2017-03-26 03:00:00    6
15 2017-03-26 04:00:00    7

df2
              datetime Var2
1  2016-10-29 22:00:00   56
2  2016-10-29 23:00:00   43
3  2016-10-30 00:00:00   23
4  2016-10-30 01:00:00   14
5  2016-10-30 02:00:00   51
6  2016-10-30 03:00:00   27
7  2016-10-30 04:00:00   89
8  2016-10-30 05:00:00   76
9  2017-03-25 22:00:00   56
10 2017-03-25 23:00:00    4
11 2017-03-26 00:00:00   35
12 2017-03-26 01:00:00   23
13 2017-03-26 02:00:00    4
14 2017-03-26 03:00:00   62
15 2017-03-26 04:00:00   84

Когда я меняю формат даты-времени df2 $ с Europe/Paris на UTC, это происходит:

library(lubridate)
df2$datetime<-with_tz(df2$datetime,"UTC")

df2
              datetime Var2
1  2016-10-29 20:00:00   56
2  2016-10-29 21:00:00   43
3  2016-10-29 22:00:00   23
4  2016-10-29 23:00:00   14
5  2016-10-30 00:00:00   51
6  2016-10-30 02:00:00   27 # Data at 01:00:00 is missing
7  2016-10-30 03:00:00   89
8  2016-10-30 04:00:00   76
9  2017-03-25 21:00:00   56
10 2017-03-25 22:00:00    4
11 2017-03-25 23:00:00   35
12 2017-03-26 00:00:00   23
13 2017-03-26 00:00:00    4 # There is a duplicate at 00:00:00
14 2017-03-26 01:00:00   62
15 2017-03-26 02:00:00   84
16 2017-03-26 03:00:00   56

Есть ли другой способ преобразования df2$datetimeиз формата Europe/Paris в формат UTC, который позволяет объединять два фрейма данных без этой проблемы потери или дублирования данных?Я не понимаю, почему я должен потерять или продублировать информацию в df2.

Правильно ли было преобразование, которое я сделал в df2$datetime, чтобы объединить этот фрейм данных с df1?Для решения этой проблемы я до сих пор добавил новую строку в df2 2016-10-30 в 01:00:00, которая является средним значением между 2016-10-30 00:00:00 и 2016-10-30 02:00:00, и удалил одну строку в2017-03-26 в 00: 00: 00.

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019
#As there are some Versions of df2 I use the one shown in the Question
df2 <- read.table(text = "
              datetime Var2
1  '2016-10-29 22:00:00'   56
2  '2016-10-29 23:00:00'   43
3  '2016-10-30 00:00:00'   23
4  '2016-10-30 01:00:00'   14
5  '2016-10-30 02:00:00'   51
6  '2016-10-30 03:00:00'   27
7  '2016-10-30 04:00:00'   89
8  '2016-10-30 05:00:00'   76
9  '2017-03-25 22:00:00'   56
10 '2017-03-25 23:00:00'    4
11 '2017-03-26 00:00:00'   35
12 '2017-03-26 01:00:00'   23
13 '2017-03-26 02:00:00'    4
14 '2017-03-26 03:00:00'   62
15 '2017-03-26 04:00:00'   84
", header = TRUE)

library(lubridate)

#When you define now the timezone the content of df2 is already changed
df2$datetimeEP <- as.POSIXct(df2$datetime, format = "%Y-%m-%d %H", tz= "Europe/Paris")
#df2[13,]
#              datetime Var2          datetimeEP
#13 2017-03-26 02:00:00    4 2017-03-26 01:00:00

#For me it looks like that your recorded times don't consider "daylight savings time".
#So your have to uses e.g. "Etc/GMT-1" instead of "Europe/Paris"
df2$datetimeG1 <- as.POSIXct(df2$datetime, format = "%Y-%m-%d %H", tz= "Etc/GMT-1")
data.frame(datetime=df2$datetime, utc=with_tz(df2$datetimeG1,"UTC"))
#              datetime                 utc
#1  2016-10-29 22:00:00 2016-10-29 21:00:00
#2  2016-10-29 23:00:00 2016-10-29 22:00:00
#3  2016-10-30 00:00:00 2016-10-29 23:00:00
#4  2016-10-30 01:00:00 2016-10-30 00:00:00
#5  2016-10-30 02:00:00 2016-10-30 01:00:00
#6  2016-10-30 03:00:00 2016-10-30 02:00:00
#7  2016-10-30 04:00:00 2016-10-30 03:00:00
#8  2016-10-30 05:00:00 2016-10-30 04:00:00
#9  2017-03-25 22:00:00 2017-03-25 21:00:00
#10 2017-03-25 23:00:00 2017-03-25 22:00:00
#11 2017-03-26 00:00:00 2017-03-25 23:00:00
#12 2017-03-26 01:00:00 2017-03-26 00:00:00
#13 2017-03-26 02:00:00 2017-03-26 01:00:00
#14 2017-03-26 03:00:00 2017-03-26 02:00:00
#15 2017-03-26 04:00:00 2017-03-26 03:00:00

#You can use "dst" to see if datetime of a time zone has "daylight savings time"
dst(df2$datetimeEP)
dst(df2$datetimeG1)
dst(with_tz(df2$datetimeEP,"UTC"))
dst(with_tz(df2$datetimeG1,"UTC"))

#If your recorded times consider "daylight savings time" then you HAVE a gap and an overlap.
0 голосов
/ 08 апреля 2019

Я обнаружил, что мой оригинал df2 должен выглядеть следующим образом:

df2
              datetime Var1
1  2016-10-29 22:00:00    4 # This is time in format "GMT+2". It corresponds to 20:00 UTC
2  2016-10-29 23:00:00   56 # This is time in format "GMT+2". It corresponds to 21:00 UTC
3  2016-10-30 00:00:00   76 # This is time in format "GMT+2". It corresponds to 22:00 UTC
4  2016-10-30 01:00:00   54 # This is time in format "GMT+2". It corresponds to 23:00 UTC
5  2016-10-30 02:00:00   34 # This is time in format "GMT+2". It corresponds to 00:00 UTC
6  2016-10-30 02:00:00    3 # This is time in format "GMT+1". It corresponds to 01:00 UTC
7  2016-10-30 03:00:00    4 # This is time in format "GMT+1". It corresponds to 02:00 UTC
8  2016-10-30 04:00:00    6 # This is time in format "GMT+1". It corresponds to 03:00 UTC
9  2016-10-30 05:00:00   78 # This is time in format "GMT+1". It corresponds to 04:00 UTC
10 2017-03-25 22:00:00   23 # This is time in format "GMT+1". It corresponds to 21:00 UTC 
11 2017-03-25 23:00:00   12 # This is time in format "GMT+1". It corresponds to 22:00 UTC 
12 2017-03-26 00:00:00    3 # This is time in format "GMT+1". It corresponds to 23:00 UTC 
13 2017-03-26 01:00:00    5 # This is time in format "GMT+1". It corresponds to 00:00 UTC 
14 2017-03-26 03:00:00    6 # This is time in format "GMT+2". It corresponds to 01:00 UTC 
15 2017-03-26 04:00:00    7 # This is time in format "GMT+2". It corresponds to 02:00 UTC 
16 2017-03-26 05:00:00   76 # This is time in format "GMT+2". It corresponds to 03:00 UTC 

Однако мой оригинал df2 не содержит дублированных или потерянных данных о времени.Это так:

df2
              datetime Var1
1  2016-10-29 22:00:00    4
2  2016-10-29 23:00:00   56
3  2016-10-30 00:00:00   76
4  2016-10-30 01:00:00   54
5  2016-10-30 02:00:00   34
6  2016-10-30 03:00:00    3
7  2016-10-30 04:00:00    4
8  2016-10-30 05:00:00    6
9  2017-03-25 22:00:00   78
10 2017-03-25 23:00:00   23
11 2017-03-26 00:00:00   12
12 2017-03-26 01:00:00    3
13 2017-10-30 02:00:00    5
14 2017-03-26 03:00:00    6
15 2017-03-26 04:00:00    7
16 2017-03-26 05:00:00   76

Когда я применил код R df2$datetime<-with_tz(df2$datetime,"UTC"), это происходит:

df2
              datetime Var1
1  2016-10-29 20:00:00    4
2  2016-10-29 21:00:00   56
3  2016-10-29 22:00:00   76
4  2016-10-29 23:00:00   54
5  2016-10-30 00:00:00   34
6  2016-10-30 02:00:00    3 # I have to add mannually a new row between the times "00:00" and "02:00"
7  2016-10-30 03:00:00    4
8  2016-10-30 04:00:00    6
9  2017-03-25 21:00:00   78
10 2017-03-25 22:00:00   23
11 2017-03-25 23:00:00   12
12 2017-03-26 00:00:00    3
13 2017-10-30 01:00:00    5 # I have to remove mannually one of the rows refered to the time "01:00".
14 2017-03-26 01:00:00    6
15 2017-03-26 02:00:00    7
16 2017-03-26 03:00:00   76

Если у моего оригинала df2 было одно дублирование в 02:0000:00 30 октября и разрыв 26 марта между «01:00» и «03:00», я получу с кодом R df2$datetime<-with_tz(df2$datetime,"UTC") это:

df2
              datetime Var1
1  2016-10-29 20:00:00    4
2  2016-10-29 21:00:00   56
3  2016-10-29 22:00:00   76
4  2016-10-29 23:00:00   54
5  2016-10-30 00:00:00   34
6  2016-10-30 00:00:00    3 # I just have to change "00:00:00" for "01:00"
7  2016-10-30 02:00:00    4
8  2016-10-30 03:00:00    6
9  2016-10-30 04:00:00   78
10 2017-03-25 21:00:00   23
11 2017-03-25 22:00:00   12
12 2017-03-25 23:00:00    3
13 2017-03-26 00:00:00    5
14 2017-03-26 01:00:00    6
15 2017-03-26 02:00:00    7
16 2017-03-26 03:00:00   76
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...