R: временная метка xts отличается от реальной временной метки данных на 1 миллисекунду - PullRequest
0 голосов
/ 03 мая 2018

Итак, у меня есть следующие данные.

tt <- structure(list(Timestamp = c("2018-03-01 09:51:59.969", "2018-03-01 09:51:59.969", 
"2018-03-01 09:51:59.970", "2018-03-01 09:51:59.971", "2018-03-01 09:51:59.987", 
"2018-03-01 09:51:59.988"), Mid_Px = c(30755.5, 30755, 30755.5, 
30756, 30756.5, 30756.5)), .Names = c("Timestamp", "Mid_Px"), class = "data.frame", row.names = 85774:85779)

, который выглядит так:

                    Timestamp  Mid_Px
85774 2018-03-01 09:51:59.969 30755.5
85775 2018-03-01 09:51:59.969 30755.0
85776 2018-03-01 09:51:59.970 30755.5
85777 2018-03-01 09:51:59.971 30756.0
85778 2018-03-01 09:51:59.987 30756.5
85779 2018-03-01 09:51:59.988 30756.5

Когда я пытаюсь создать из него объект xts с помощью приведенного ниже кода, все становится плохо.

tt_ts <- strptime(tt[,1],"%Y-%m-%d %H:%M:%OS")
tt_ts
[1] "2018-03-01 09:51:59.969 CST" "2018-03-01 09:51:59.969 CST" "2018-03-01 09:51:59.970 CST" "2018-03-01 09:51:59.971 CST" "2018-03-01 09:51:59.987 CST"
[6] "2018-03-01 09:51:59.988 CST"
xts(x=tt[,c(-1)], order.by=tt_ts)
                           [,1]
2018-03-01 09:51:59.969 30755.5
2018-03-01 09:51:59.969 30755.0
2018-03-01 09:51:59.970 30755.5
2018-03-01 09:51:59.970 30756.0
2018-03-01 09:51:59.986 30756.5
2018-03-01 09:51:59.987 30756.5

Обратите внимание, что миллисекунды неверны в строках 4,5 и 6.

Что я здесь не так сделал? Как я могу исправить это, чтобы отобразить правильную метку времени?

1 Ответ

0 голосов
/ 03 мая 2018

Это похоже на R проблему с округлением в миллисекундах . Одно простое решение было бы добавить 0,5 мс, как предлагается там:

tt_ts <- strptime(tt[,1],"%Y-%m-%d %H:%M:%OS") + 0.0005
xts::xts(x=tt[,c(-1)], order.by=tt_ts)
#                            [,1]
# 2018-03-01 09:51:59.969 30755.5
# 2018-03-01 09:51:59.969 30755.0
# 2018-03-01 09:51:59.970 30755.5
# 2018-03-01 09:51:59.971 30756.0
# 2018-03-01 09:51:59.987 30756.5
# 2018-03-01 09:51:59.988 30756.5

Мы можем видеть это на простом примере:

st <- strptime("2018-03-01 09:51:59.971", "%Y-%m-%d %H:%M:%OS")
format(st, "%Y-%m-%d %H:%M:%OS3")
#> [1] "2018-03-01 09:51:59.971"
pt <- as.POSIXct(st)
format(pt, "%Y-%m-%d %H:%M:%OS3")
#> [1] "2018-03-01 09:51:59.970"

После преобразования в POSIXct неверная мс. Увеличивая точность вывода, мы видим, что число с плавающей запятой, используемое для представления времени, чуть ниже требуемого значения, но R обрезает число вместо его округления:

format(pt, "%Y-%m-%d %H:%M:%OS6")
#> [1] "2018-03-01 09:51:59.970999"

Сдвиг на половину необходимой точности исправляет это.

format(pt + 0.0005, "%Y-%m-%d %H:%M:%OS3")
#> [1] "2018-03-01 09:51:59.971"

Как правило, если x является числом с 3 десятичными цифрами, любое число в открытом диапазоне ( x - 0,0005, x + 0,0005) будет округляется до x . При усечении это будет работать для тех, кто находится в пределах [ x , x + 0,0005). Но те, которые в пределах ( x - 0,0005, x ) будут представлены как x - 0,001, как вы заметили. Если мы передвинем соответствующее число на 0,0005 перед усечением, мы говорим о диапазоне ( x , x + 0,001). Все эти числа будут усечены до x , как и хотелось.

Я исключаю очки x & pm; 0,0005, поскольку существуют разные правила их округления, и фактическое число с плавающей запятой, представляющее точку времени, будет намного ближе к желаемому значению, чем это.

РЕДАКТИРОВАТЬ: Относительно вопроса в комментариях о принятии различий: Там не должно иметь значения, добавляете ли вы полмиллисекунды или нет, если вы добавляете это в обе точки. Пример с моментом времени, который нуждается в самостоятельной корректировке:

st1 <- strptime("2018-03-01 09:51:59.971", "%Y-%m-%d %H:%M:%OS")
format(st1, "%Y-%m-%d %H:%M:%OS3")                              
#> [1] "2018-03-01 09:51:59.970"
pt1 <- as.POSIXct(st1)                                          
format(pt1, "%Y-%m-%d %H:%M:%OS3")                              
#> [1] "2018-03-01 09:51:59.970"
format(pt1 + 0.0005, "%Y-%m-%d %H:%M:%OS3")                     
#> [1] "2018-03-01 09:51:59.971"

И момент времени, который не нуждается в настройке:

st2 <- strptime("2018-03-01 09:51:59.969", "%Y-%m-%d %H:%M:%OS")
format(st2, "%Y-%m-%d %H:%M:%OS3")                              
#> [1] "2018-03-01 09:51:59.969"
pt2 <- as.POSIXct(st2)                                          
format(pt2, "%Y-%m-%d %H:%M:%OS3")                              
#> [1] "2018-03-01 09:51:59.969"
format(pt2 + 0.0005, "%Y-%m-%d %H:%M:%OS3")                     
#> [1] "2018-03-01 09:51:59.969"

Разница такая же, независимо от какой-либо корректировки:

difftime(pt1, pt2, "secs")                                      
#> Time difference of 0.001999855 secs
difftime(pt1 + 0.0005, pt2 + 0.0005, "secs")                    
#> Time difference of 0.001999855 secs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...