#r #time
#r #время
Вопрос:
У меня есть фрейм данных, где первый столбец — время. Мой текущий результат выглядит так:
0:0:0
0:0:0
5:43:42 вечера
5:43:52 вечера
Я пытаюсь заставить часть моего кода искать любые строки, в которых есть значение 0: 0: 0, и вычесть 10 секунд из ближайшей строки со значением в ней. Желаемый результат будет выглядеть следующим образом:
5:43:22 вечера
5:43:32 вечера
5:43:42 вечера
5:43:52 вечера
Я написал эту часть кода, чтобы сделать это за себя. Он выполняется без ошибок, но фактически не изменяет никаких значений.
entries<-length(data$Time)
for(j in entries:1)
if(data[j,1]=="0:0:0"){
for(k in j-1:1)
if(data[k,1]!="0:0:0"){
data[k,1] <- as.POSIXct(data[k,1], format = "%H:%M:%S")
value <- format(data[k,1] seconds(10))
data[j,1] <- value
break
}
}
Есть предложения по созданию этого?
Комментарии:
1. Не могли бы вы опубликовать данные, которые вы используете, каковы выходные данные и чего вы хотите достичь?
2. Что происходит, когда время 0: 0: 0 имеет равноудаленные значения с обеих сторон? Могут ли ненулевые значения только следовать за нулевым значением, а не предшествовать нулевому значению?
3. Я обновил вопрос, чтобы уточнить мой текущий результат и желаемый результат, пожалуйста, дайте мне знать, если это все еще неясно, мне сложно сформулировать этот вопрос. У меня могут быть ненулевые значения до и после нулевых значений. Я предполагаю, что я бы создал дополнительный оператор цикла if или for, чтобы исправить эти, но если я ошибаюсь, пожалуйста, не стесняйтесь, дайте мне знать. Я очень новичок в анализе данных и R.
4. «Он работает без ошибок»? Нет, он вообще не запускается, не могли бы вы проверить и отредактировать это, пожалуйста?
Ответ №1:
Предполагая, что последнее значение в ваших данных не будет '0:0:0'
, вы можете сделать следующее :
Замените Time
на NA
то, где находится значение 0:0:0
, и превратите их в POSIXct
класс.
library(dplyr)
df %>%
mutate(Time = na_if(Time, '0:0:0'),
Time1 = as.POSIXct(Time, format = '%T')) -> df1
Замените NA
значение, вычитая 10 секунд из следующего значения.
for(i in nrow(df1):1) {
if(is.na(df1$Time1[i])) {
df1$Time1[i] <- df1$Time1[i 1] - 10
}
}
Измените POSIXct
желаемое format
(H: M: S), которое нам нужно.
df1 %>%
mutate(Time = format(Time1, '%T'),
Time1 = NULL) -> result
result
# Time
#1 05:43:22
#2 05:43:32
#3 05:43:42
#4 05:43:52
данные
df <- structure(list(Time = c("0:0:0", "0:0:0", "5:43:42", "5:43:52"
)), class = "data.frame", row.names = c(NA, -4L))
Ответ №2:
Вот data.table
подход, предполагающий, что под «ближайшей строкой со значением» вы подразумеваете ближайшую следующую строку, которая не является «0: 0: 0»:
library(data.table)
DT <- data.table(Time=c("0:0:0", "0:0:0", "5:43:42 pm", "5:43:52 pm",
"0:0:0", "6:43:52 pm"), c2=LETTERS[1:6])
DT[Time=="0:0:0", Time := NA]
DT[, Time := as.POSIXct(Time, format = "%I:%M:%S %p")]
i <- which(is.na(DT$Time))
DT[, idx:=cumsum(!is.na(Time))]
DT[, idx:=rev(seq(.N)), by=idx]
DT[, Time := nafill(Time, type="nocb")]
DT[i, Time:=Time - (10*idx)][, idx:=NULL]
DT[, Time := format(Time, '%I:%M:%S %p')][]
#> Time c2
#> 1: 05:43:22 PM A
#> 2: 05:43:32 PM B
#> 3: 05:43:42 PM C
#> 4: 05:43:52 PM D
#> 5: 06:43:42 PM E
#> 6: 06:43:52 PM F
Создано 2020-12-30 пакетом reprex (версия 0.3.0)