R语言:计算温度类别连续周期的持续时长(dplyr实现问题)
R语言:计算温度类别连续周期的持续时长(dplyr实现问题)
看起来你现在的核心问题是:用group_by(Temp_cat)会把所有同类别行归为一组,算出的是该类别全局的总时长,但你需要的是**连续出现的同Temp_cat段(也就是“周期”)**的单独时长,对吧?我来帮你调整代码解决这个问题。
问题根源
你当前的代码是按Temp_cat全局分组,所以会把第一次出现的Temp_cat=3和后来再次出现的Temp_cat=3合并计算,完全忽略了它们是两个独立的连续周期。我们需要先给每个连续的同类别段分配唯一的分组ID,再基于这个ID计算时长。
解决方案代码
首先,先把你的示例数据整理成可运行的R代码(方便测试):
library(dplyr) library(lubridate) # 你的示例数据 df <- tibble( Temp = c(3.47, 3.37, 3.31, 3.25, 3.14, 3.1, 1.95, 1.86, 1.89, 1.85, -0.86, -0.89, -0.85, 8.37, 8.98, 9.4, 8.8, 3.47, 3.37, 3.31, 3.25, 3.14, 7.36, 7.12), Time = dmy_hm(c("15.08.2025 00:01", "15.08.2025 00:03", "15.08.2025 00:05", "15.08.2025 00:07", "15.08.2025 00:09", "15.08.2025 00:11", "15.08.2025 00:13", "15.08.2025 00:15", "15.08.2025 00:17", "15.08.2025 00:19", "15.08.2025 00:21", "15.08.2025 00:23", "15.08.2025 00:25", "15.08.2025 00:27", "15.08.2025 00:29", "15.08.2025 00:31", "15.08.2025 00:33", "15.08.2025 00:35", "15.08.2025 00:37", "15.08.2025 00:39", "15.08.2025 00:41", "15.08.2025 00:43", "15.08.2025 00:45", "15.08.2025 00:47")), Temp_cat = c(3,3,3,3,3,3,2,2,2,2,2,2,2,4,4,4,4,3,3,3,3,3,4,4) )
接下来,我们给每个连续的Temp_cat周期分配唯一ID,这里有两种方法:
方法1:用data.table的rleid()(简洁推荐)
rleid()是data.table包的函数,专门用来生成连续相同值的分组ID,非常好用:
library(data.table) df_with_cycles <- df %>% mutate(cycle_id = rleid(Temp_cat)) # 给连续同Temp_cat的行分配同一个cycle_id
方法2:纯dplyr实现(无需额外安装包)
如果你不想装data.table,用dplyr也可以模拟这个逻辑:
df_with_cycles <- df %>% mutate( # 标记当前行和上一行的Temp_cat是否不同(第一行默认和自己相同,所以标记为FALSE) is_new_cycle = Temp_cat != lag(Temp_cat, default = first(Temp_cat)), # 累加标记得到连续分组的ID cycle_id = cumsum(is_new_cycle) ) %>% select(-is_new_cycle) # 删掉中间变量
最后,按cycle_id分组计算每个周期的时长:
cycle_duration <- df_with_cycles %>% group_by(cycle_id, Temp_cat) %>% summarise( start_time = first(Time), end_time = last(Time), duration_mins = as.numeric(difftime(end_time, start_time, units = "mins")), .groups = "drop" # 取消分组 ) # 转换成你想要的自然语言输出格式 cycle_duration %>% mutate( # 给每个周期编序号,方便生成描述 cycle_num = row_number(), description = case_when( cycle_num == 1 ~ paste0(duration_mins, " min in first cycle of Temp_cat ", Temp_cat), TRUE ~ paste0(duration_mins, " min in Temp_cat ", Temp_cat, " again") ) ) %>% pull(description)
运行结果
执行后会得到以下输出:
[1] "10 min in first cycle of Temp_cat 3" [2] "12 min in Temp_cat 2 again" [3] "6 min in Temp_cat 4 again" [4] "8 min in Temp_cat 3 again" [5] "2 min in Temp_cat 4 again"
小说明
注意你的期望输出里写的Temp_cat4第一个周期是4分钟,但根据你提供的测量时间(00:27到00:33),实际时长是6分钟。如果你的需求是计算测量点之间的间隔总和(而不是结束时间减开始时间),可以把duration_mins改成(n()-1)*2——因为每2分钟测一次,n个测量点之间有n-1个间隔,每个间隔2分钟。
内容来源于stack exchange
相关产品推荐
相关产品推荐

