R中如何按组选取和最小的连续36行数据并绘制高亮分面柱状图
实现方案
依赖包
首先确认已加载所需工具包:
library(tidyverse) library(zoo) library(gghighlight)
数据处理逻辑修正
你原有代码的核心问题有两个:一是mutate中使用df$SumsofOnline的写法会忽略分组逻辑,直接调用全局数据框的列,导致分组计算失效;二是rollapply默认返回的结果长度与原分组行数不匹配,无法直接关联回原始行。
我们通过新增标记列的方式,同时满足「提取对应行」和「后续绘图高亮」的需求:
df_processed <- df %>% group_by(week) %>% # 按日期升序排列,保证滑动窗口的时间连续性,.by_group保证在分组内排序 arrange(Date, .by_group = TRUE) %>% # 过滤掉总行数不足36的分组,避免后续计算报错 filter(n() >= 36) %>% # 计算左对齐的36行滑动和,不足36行的位置填充NA,每个值对应当前行作为起始的36行总和 mutate(roll_sum = rollapply(Online_h, width = 36, FUN = sum, align = "left", fill = NA)) %>% # 定位当前分组内最小滑动和对应的窗口起始行号 mutate(min_window_start = which.min(roll_sum)) %>% # 标记当前行是否属于最小和对应的36行窗口 mutate(is_min_window = row_number() %in% min_window_start:(min_window_start + 35)) %>% ungroup()
如果需要单独提取每组符合要求的36条原数据,直接在上述代码末尾加filter(is_min_window == TRUE)即可。
绘图实现
直接使用新增的is_min_window标记列配合gghighlight实现分面高亮效果:
df_processed %>% ggplot(aes(x = Date, y = Online_h)) + # geom_col等价于geom_bar(stat = "identity"),写法更简洁 geom_col() + facet_grid(rows = vars(week)) + gghighlight( is_min_window == TRUE, # 非高亮柱形降低透明度 unhighlighted_params = list(alpha = 0.3) )
gghighlight会自动适配分面逻辑,每个week分面内仅高亮对应分组的最小和窗口行,无需额外配置分组参数。
内容的提问来源于stack exchange,提问作者Vahram
相关产品推荐
相关产品推荐

