如何用R/tidyverse计算分组内近6个月唯一machine_ID数量?
使用tidyverse实现分组近6个月唯一机器ID计数
解决方案1:结合slider包(推荐,高效简洁)
首先加载所需工具包,构造可复现的样本数据:
library(tidyverse) library(lubridate) library(slider) set.seed(123) df <- tibble( date = seq(as.Date(paste0("2010-01-",runif(1,1,25))), by = "month", length.out = 24), machine_ID = sample(letters[1:10],size = 24,replace = T), machine_cat = rep(c(1,2),12) )
执行分组滑动窗口计算:
df_result <- df %>% arrange(machine_cat, date) %>% group_by(machine_cat) %>% mutate( last6m = slide_index_dbl( .x = machine_ID, .i = date, .f = ~n_distinct(.x), .before = months(6) ) ) %>% ungroup()
代码说明:
arrange(machine_cat, date):确保每个机器类别内的记录按日期升序排列,为滑动窗口计算提供有序基础。group_by(machine_cat):限定统计范围为同一机器类别内的记录。slide_index_dbl:slider包专为基于索引的滑动窗口设计的函数:.x指定要统计的目标向量(machine_ID).i指定窗口的时间索引(date).f定义窗口内的计算逻辑,n_distinct(.x)统计唯一ID数量.before = months(6)明确窗口范围为当前日期往前推6个月的所有记录
解决方案2:仅用tidyverse核心包(无需额外依赖)
如果不想安装slider包,可使用purrr实现:
library(tidyverse) library(lubridate) set.seed(123) df <- tibble( date = seq(as.Date(paste0("2010-01-",runif(1,1,25))), by = "month", length.out = 24), machine_ID = sample(letters[1:10],size = 24,replace = T), machine_cat = rep(c(1,2),12) ) df_result <- df %>% arrange(machine_cat, date) %>% group_by(machine_cat) %>% mutate( last6m = map_dbl(row_number(), ~{ current_date <- date[.x] window_range <- current_date %m-% months(6) n_distinct(machine_ID[date >= window_range & date <= current_date]) }) ) %>% ungroup()
代码说明:
map_dbl(row_number(), ~{...}):遍历当前组内的每一行,针对每行的日期筛选出近6个月内的所有machine_ID。n_distinct(...):统计筛选出的ID中的唯一值数量,最终返回数值型结果。
内容的提问来源于stack exchange,提问作者MariusJ
相关产品推荐
相关产品推荐

