Я извлек десятичный час из каждого предоставленного вами кадра данных, чтобы я мог спросить, найдено ли значение в течение этого десятичного часа. Но сначала вам нужно объединить наборы данных на основе идентификатора (при условии, что у вас есть другие идентификаторы) и даты (при условии, что в день существует только одно состояние; или, другими словами, в наборе данных df.state существует одна дата в день).
id <- c("A","A","A","A","A","A","A","A","A","A","A")
date <- c("2018-11-12","2018-11-12","2018-11-12","2018-11-12","2018-11-12",
"2018-11-12","2018-11-12","2018-11-14","2018-11-14","2018-11-14",
"2018-11-12")
hour <- c(8,8,9,9,13,13,16,6,7,19,7)
min <- c(47,59,6,18,22,36,12,32,12,21,47)
value <- c(70,70,86,86,86,74,81,77,79,83,91)
df.sample <- data.frame(id,date,hour,min,value,stringsAsFactors = F)
df.sample$date <- as.Date(df.sample$date,format="%Y-%m-%d")
df.sample$dec.hour <- as.numeric(df.sample$hour) +
as.numeric(df.sample$min)/60
Все, что я добавил выше, это последние две строки для вычисления десятичного часа из предоставленных вами значений часов и минут
id <- c("A","A","A")
starttime <- c("2018-11-12 08:59:00","2018-11-14 06:24:17","2018-11-15 09:17:00")
endtime <- c("2018-11-12 15:57:00","2018-11-14 17:22:16","2018-11-15 12:17:32")
state <- c("Pass","Pass","Pass")
df.state <- data.frame(id,starttime,endtime,state,stringsAsFactors = F)
Здесь я добавил вектор даты (для слияния). Я произвольно выбрал время начала, предполагая, что дата начала и время окончания всегда совпадают.
df.state$date <- as.Date(df.state$starttime,format="%Y-%m-%d")
Тогда я получу десятичный час для времени начала и окончания, в эту дату
t.str <- strptime(df.state$starttime, "%Y-%m-%d %H:%M:%S")
df.state$dec.hour.start <- as.numeric(format(t.str, "%H")) +
as.numeric(format(t.str, "%M"))/60
t.end <- strptime(df.state$endtime, "%Y-%m-%d %H:%M:%S")
df.state$dec.hour.end <- as.numeric(format(t.end, "%H")) +
as.numeric(format(t.end, "%M"))/60
объединить кадры данных по идентификатору и дате
df<-merge(df.sample, df.state, by=c("id","date"))
, если десятичный час выборки находится в пределах начального или конечного десятичного часа (на эту дату), тогда вернуть TRUE для состояния.
df<-df %>%
mutate(state = dec.hour >= dec.hour.start & dec.hour <= dec.hour.end)
Теперь, если вы хотите избавиться от всех этих дополнительных столбцов, которые я создал (так что это похоже на ваш желаемый результат):
df<-df[,-c(6:8,10:11)]
Поскольку df $ state является логическим, вы должны сначала превратить значения в символы, если вы хотите изменить TRUE для передачи и FALSE на пробел:
df$state<-as.character(df$state)
df$state[df$state=="TRUE"]<-"pass"
df$state[df$state=="FALSE"]<-""
Взгляните:
df
> df
id date hour min value state
1 A 2018-11-12 8 47 70
2 A 2018-11-12 8 59 70 pass
3 A 2018-11-12 9 6 86 pass
4 A 2018-11-12 9 18 86 pass
5 A 2018-11-12 13 22 86 pass
6 A 2018-11-12 13 36 74 pass
7 A 2018-11-12 16 12 81
8 A 2018-11-12 7 47 91
9 A 2018-11-14 6 32 77 pass
10 A 2018-11-14 7 12 79 pass
11 A 2018-11-14 19 21 83
Я использовал этот пост: извлекать часы и секунды из POSIXct для построения графиков в R , чтобы извлекать десятичные часы
и вот этот: Проверьте, находится ли значение в пределах диапазона? , чтобы узнать, было ли время выборки в пределах времени вашего состояния.