如何处理tibble列表中每个tibble的所有行以查找温度低于8℃累计4次的行索引
问题核心原因
- 现有代码的外层循环仅遍历了列表里的106个tibble,没有嵌套遍历每个tibble内部的数千行数据,自然只能读取每个tibble的第一行
- 全局共用同一组计数变量
temp、pos_r,没有为每个tibble单独重置计数器,计数结果会在不同tibble间串用 - R的for循环不会响应你手动修改的循环变量
i = i + 1,这部分逻辑完全无效
推荐实现方案
方案1:tidyverse简洁实现(适配tibble结构)
用purrr遍历列表+dplyr做累计计数,代码可读性高不易出错:
library(tidyverse) result <- map_dbl(data_sensor, function(df) { df %>% # 生成温度低于8的累计计数 mutate(cnt = cumsum(temperature < 8.0)) %>% # 取累计到第4次的第一行行号 filter(cnt == 4) %>% slice_head(n = 1) %>% pull(.row_names) %>% as.integer() })
注:如果你的列名实际为大写Temperature,请对应替换代码中的列名字符串
如果某个tibble里温度低于8的总次数不足4次,对应位置会返回NA,符合你的输出习惯。
方案2:基础R循环修正版
如果你习惯用for循环实现,修正后的代码如下:
# 提前初始化结果向量,运行效率更高 posx <- integer(length(data_sensor)) for (i in seq_along(data_sensor)) { # 每个tibble单独初始化计数器 temp_cnt <- 0 target_row <- NA_integer_ current_df <- data_sensor[[i]] # 遍历当前tibble的所有行 for (r in seq_len(nrow(current_df))) { if (current_df$temperature[r] < 8.0) { temp_cnt <- temp_cnt + 1 # 累计到第4次直接记录行号,跳出当前循环处理下一个tibble if (temp_cnt == 4) { target_row <- r break } } } posx[i] <- target_row }
内容的提问来源于stack exchange,提问作者Marc_P
相关产品推荐
相关产品推荐

