在R中基于列生成唯一ID并按该ID计算均值
给连续事件片段生成唯一ID并计算分组均值
1. 构造示例数据
先把你提供的示例数据转换成数据框:
df <- data.frame( Event = c("A", "A", "A", "B", "B", "C", "C", "A", "A"), Val = c(3, 5, 1, 8, 2, 1, 3, 2, 5) )
2. 生成连续事件的唯一ID
核心思路是先识别每个连续事件块,再给每个Event下的块按出现顺序编号,最后拼接成目标ID:
library(dplyr) df <- df %>% # 标记每个连续事件块的全局编号 mutate(block_id = cumsum(c(TRUE, Event[-1] != Event[-n()]))) %>% # 按Event分组,给每个Event的块分配组内序号(比如A的第一个块是1,第二个是2) group_by(Event) %>% mutate(event_seq = dense_rank(block_id)) %>% ungroup() %>% # 拼接成目标ID mutate(ID = paste0(Event, event_seq)) %>% # 可按需删除中间辅助列 select(-block_id, -event_seq)
生成的结果如下:
| Event | Val | ID |
|---|---|---|
| A | 3 | A1 |
| A | 5 | A1 |
| A | 1 | A1 |
| B | 8 | B1 |
| B | 2 | B1 |
| C | 1 | C1 |
| C | 3 | C1 |
| A | 2 | A2 |
| A | 5 | A2 |
3. 按ID分组计算Val的均值
直接分组聚合即可:
mean_df <- df %>% group_by(ID) %>% summarise(Val_mean = mean(Val)) %>% ungroup()
最终均值结果:
| ID | Val_mean |
|---|---|
| A1 | 3 |
| A2 | 3.5 |
| B1 | 5 |
| C1 | 2 |
基础R实现(无需dplyr)
如果不想依赖tidyverse包,用基础R也能完成:
# 生成连续块的全局编号 df$block_id <- cumsum(c(TRUE, df$Event[-1] != df$Event[-nrow(df)])) # 给每个Event的块分配组内序号 df$event_seq <- ave(df$block_id, df$Event, FUN = function(x) match(x, unique(x))) # 拼接ID df$ID <- paste0(df$Event, df$event_seq) # 计算均值 mean_df <- aggregate(Val ~ ID, data = df, FUN = mean)
内容的提问来源于stack exchange,提问作者Karthik
相关产品推荐
相关产品推荐

