如何对满足两列特定条件的连续行计算均值并合并?
问题
我有如下简化版的dataframe:
lab_id weeks GM.CSF IFNa2 IFNg IL10 IL12p40 1 op1 2020 G4 week_1 1.6900 13.0258 5.0755 3.3068 1.3 2 op1 2020 G4 week_4 1.6900 4.4113 3.9592 2.0100 1.3 3 op10 2020 G4 week_4 2.4236 8.3186 41.7559 2.0100 1.3 4 op10 2020 G4 week_4 3.2600 18.3118 12.5456 2.0100 1.3
我需要筛选出满足以下条件的连续行并处理:
- 连续两行的lab_id值相同;
- 若两行的weeks值不同,则不做处理;
- 若两行的weeks值相同,则计算这两行数值列(GM.CSF、IFNa2等)的均值,并用该行替换原两行。
例如行3和行4满足条件,处理后应得到:
lab_id weeks GM.CSF IFNa2 ... 3 op10 2020 G4 week_4 2.8418 13.3152 ...
我尝试用rowise()结合if_else,以及mutate()标记重复行,但均未成功,现有疑问:
- 是否有可同时评估列与连续行的函数?
- 如何改进当前的实现思路?
解决方案
疑问解答
- 有这类函数:
dplyr包中的lag()和lead()可以获取当前行的上一行/下一行数据,实现连续行的列值对比;另外group_by()结合分组逻辑,也能完成对同组连续行的处理。 - 你的逐行判断思路过于复杂,更高效的方式是先通过分组锁定目标行,再批量计算均值——如果严格要求仅处理连续行,可以先标记连续组再操作;若只要同
lab_id+weeks的行就合并,直接分组求均值即可。
具体实现代码
情况1:合并所有同lab_id+weeks的行(不限制是否连续)
如果需求本质是合并所有同lab_id且同weeks的行,用以下代码最简洁:
library(dplyr) # 假设数据框名为df processed_df <- df %>% group_by(lab_id, weeks) %>% summarise(across(c(GM.CSF, IFNa2, IFNg, IL10, IL12p40), mean), .groups = "drop")
情况2:仅合并连续的同lab_id+weeks的行
如果严格要求只处理连续的目标行,先标记连续组再分组计算:
library(dplyr) processed_df <- df %>% # 生成连续组ID:当前行与上一行的lab_id+weeks不同时,组号+1 mutate(group_id = cumsum(!(lab_id == lag(lab_id, default = "") & weeks == lag(weeks, default = "")))) %>% # 按连续组分组计算均值 group_by(group_id) %>% summarise( lab_id = first(lab_id), weeks = first(weeks), across(c(GM.CSF, IFNa2, IFNg, IL10, IL12p40), mean), .groups = "drop" ) %>% select(-group_id) # 移除临时组号列
代码说明
lag():获取上一行的lab_id和weeks,与当前行对比判断是否属于同一连续组;cumsum():通过累加布尔值(TRUE为1,FALSE为0)生成唯一的连续组ID;group_by()+summarise()+across():对每组内的数值列批量计算均值,同时保留分组的lab_id和weeks信息。
内容的提问来源于stack exchange,提问作者Someone_1313
相关产品推荐
相关产品推荐

