我会为此使用data.table,当然还有其他方法。
library( data.table )
setDT( df )
temp.threshold <- 18
首先创建一列,显示数据中每个值的上一个值。这将有助于找到温度高于阈值的点。
df[ , lag := shift( Temp, fill = 0, type = "lag" ) ]
现在使用之前的值列与Temp 列进行比较。将温度上升到阈值以上的每个点标记为 1,将所有其他点标记为 0。
df[ , group := 0L
][ Temp > temp.threshold & lag <= temp.threshold, group := 1L ]
现在我们可以获得该新列的cumsum,它将在温度升至阈值以上后为每个序列提供其自己的group ID。
df[ , group := cumsum( group ) ]
现在我们可以去掉所有不超过阈值的值。
df <- df[ Temp > temp.threshold, ]
并通过查找每个“组”的“学位小时数”来总结剩下的内容。
bygroup <- df[ , sum( Temp - temp.threshold ), by = group ]
我稍微修改了您的输入数据,以提供一些数据超过阈值的测试事件:
structure(list(num = c(1L, 2L, 3L, 4L, 5L, 21189L, 21190L, 21191L,
21192L, 21193L, 21194L), Temp = c(14.026, 13.714, 13.25, 20,
19, 12.437, 12.558, 12.703, 12.896, 21, 21)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -11L), .Names = c("num",
"Temp"), spec = structure(list(cols = structure(list(num = structure(list(), class = c("collector_integer",
"collector")), Temp = structure(list(), class = c("collector_double",
"collector"))), .Names = c("num", "Temp")), default = structure(list(), class = c("collector_guess",
"collector"))), .Names = c("cols", "default"), class = "col_spec"))
有了这些数据,这是上面代码的输出(注意$V1 是“度小时”):
> bygroup
group V1
1: 1 3
2: 2 6