Как установить начальную дату для нового столбца даты и связать ее со временем для изменения на следующий день

#r #date #datetime

#r #Дата #дата и время

Вопрос:

У меня есть набор данных, в котором записано только время, но не дата, поэтому:

 >accel
UTC.Time Milliseconds X.Acc Y.Acc Z.Acc Temp
23:59:59          813  0.25 -0.81 -0.50    0 
23:59:59          844  0.25 -0.81 -0.50    0 
23:59:59          875  0.25 -0.81 -0.50    0 
23:59:59          906  0.25 -0.81 -0.50    0
23:59:59          938  0.25 -0.81 -0.50    0 
23:59:59          969  0.25 -0.81 -0.50    0
00:00:00            0  0.25 -0.81 -0.50    0 
00:00:00           31  0.25 -0.81 -0.50    0 
00:00:00           63  0.25 -0.81 -0.50    0 
00:00:00           94  0.31 -0.81 -0.50    0 
00:00:00          125  0.25 -0.81 -0.50    0 
00:00:00          156  0.25 -0.81 -0.50    0 
 

Я знаю, когда начинается мой набор данных («2015/03/15»), и могу добавить столбец даты с помощью:

 >  m<-paste("03")
>  d<-paste("05")
>  accel$UTC.Date<-paste("2015/",m,"/",d,"", sep="")
 

У меня есть множество дат для разных файлов, поэтому я настроил так, но это создает новый UTC.Столбец даты с датами в виде:

 >accel
UTC.Time Milliseconds X.Acc Y.Acc Z.Acc Temp UTC.Date
23:59:59          813  0.25 -0.81 -0.50    0 2015/03/05
23:59:59          844  0.25 -0.81 -0.50    0 2015/03/05
23:59:59          875  0.25 -0.81 -0.50    0 2015/03/05
23:59:59          906  0.25 -0.81 -0.50    0 2015/03/05
23:59:59          938  0.25 -0.81 -0.50    0 2015/03/05
23:59:59          969  0.25 -0.81 -0.50    0 2015/03/05
00:00:00            0  0.25 -0.81 -0.50    0 2015/03/05
00:00:00           31  0.25 -0.81 -0.50    0 2015/03/05
00:00:00           63  0.25 -0.81 -0.50    0 2015/03/05
00:00:00           94  0.31 -0.81 -0.50    0 2015/03/05
00:00:00          125  0.25 -0.81 -0.50    0 2015/03/05
00:00:00          156  0.25 -0.81 -0.50    0 2015/03/05
 

Проблема здесь в том, что моя дата не переключилась на 2015/03/06 с полуночи, 00:00:00. Как я могу установить начальную дату и убедиться, что она соответствует времени и изменяется по мере перехода на следующий день?

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

Я пытался

 accel$UTC.Datetime<- strptime(as.character(accel$UTC.Time),format="%H:%M:%OS", tz = "UTC")
 

который дает сегодняшнюю дату и заданное время, но все равно не изменяет дату в полночь:

 >accel$UTC.Datetime
2020-12-21 23:59:59
2020-12-21 23:59:59
2020-12-21 23:59:59
2020-12-21 23:59:59
2020-12-21 23:59:59
2020-12-21 00:00:00
2020-12-21 00:00:00
2020-12-21 00:00:00
2020-12-21 00:00:00
2020-12-21 00:00:00
 

Есть ли опция «начало» или «начало», которую я пропускаю? Любая помощь в этом очень ценится

Комментарии:

1. Полночь, то есть когда происходит изменение даты, — это 23:59:59 00:00:00 не с 00:00:00 до 00:00:01 , не так ли?

2. Это очень верно, я выбрал подраздел своего кода для представления здесь, но скопировал неправильный раздел. Я все равно сталкиваюсь с ошибкой. Я повторно импортировал свои примеры, чтобы отразить это. Спасибо!

Ответ №1:

В качестве первого шага мы можем отформатировать столбец времени без даты as.POSIXct , которая добавляет Sys.Date к нему. Теперь у нас везде st.dt есть префикс.

В качестве второго шага, чтобы получить переключение дат плюс один после полуночи, мы принудительно преобразуем исходный UTC.Time столбец в цифры, удалив : и подсчитайте, где различия меньше, чем, скажем -200000 (зависит от ваших временных шагов). Их количество cumsum , умноженное на секунды дня, добавленные к датам первого шага, дают нам желаемый результат.

 st.dt <- "2015-03-05"  ## start date
dat <- within(dat,{
  UTC.Datetime <- as.POSIXct(paste(UTC.Time, Milliseconds, sep="."),
                             format="%H:%M:%OS", tz="UTC") -
    (as.POSIXct(Sys.Date(), tz="UTC") - as.POSIXct(st.dt, tz="UTC"))   
    cumsum(c(0, diff(as.numeric(gsub("\D", "", UTC.Time)))) < -200000)*86400 
})
dat
# U   TC.Time Milliseconds X.Acc Y.Acc Z.Acc Temp        UTC.Datetime
# 1  23:59:59          813  0.25 -0.81  -0.5    0 2015-03-05 23:59:59
# 2  23:59:59          844  0.25 -0.81  -0.5    0 2015-03-05 23:59:59
# 3  23:59:59          875  0.25 -0.81  -0.5    0 2015-03-05 23:59:59
# 4  00:00:00          906  0.25 -0.81  -0.5    0 2015-03-06 00:00:00
# 5  00:00:00          938  0.25 -0.81  -0.5    0 2015-03-06 00:00:00
# 6  00:00:00          969  0.25 -0.81  -0.5    0 2015-03-06 00:00:00
# 7  00:00:01            0  0.25 -0.81  -0.5    0 2015-03-06 00:00:01
# 8  00:00:01           31  0.25 -0.81  -0.5    0 2015-03-06 00:00:01
# 9  00:00:01           63  0.25 -0.81  -0.5    0 2015-03-06 00:00:01
# 10 00:00:01           94  0.31 -0.81  -0.5    0 2015-03-06 00:00:01
# 11 23:59:59          125  0.25 -0.81  -0.5    0 2015-03-06 23:59:59
# 12 00:00:01          156  0.25 -0.81  -0.5    0 2015-03-07 00:00:01
 

И это быстро:

 dat <- dat[sample(nrow(dat), 1e6, replace=T), ]
dim(dat)
# [1] 1000000       7
system.time(<code above>)
# user  system elapsed 
# 3.03    0.05    3.16 
 

Данные:

 dat <- structure(list(UTC.Time = c("23:59:59", "23:59:59", "23:59:59", 
"00:00:00", "00:00:00", "00:00:00", "00:00:01", "00:00:01", "00:00:01", 
"00:00:01", "00:00:01", "00:00:01"), Milliseconds = c(813L, 844L, 
875L, 906L, 938L, 969L, 0L, 31L, 63L, 94L, 125L, 156L), X.Acc = c(0.25, 
0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.31, 0.25, 0.25
), Y.Acc = c(-0.81, -0.81, -0.81, -0.81, -0.81, -0.81, -0.81, 
-0.81, -0.81, -0.81, -0.81, -0.81), Z.Acc = c(-0.5, -0.5, -0.5, 
-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5), Temp = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA, 
-12L))
 

Комментарии:

1. Это здорово и работает! Хотя это довольно медленно, мой компьютер застревает на пару минут. Я обрабатываю сотни файлов, есть ли более быстрый способ добиться этого? Спасибо за вашу помощь!

2. @CED нашел решение, которое примерно в десять раз быстрее! См. раздел Изменения.