R语言:基于V4分组替换V7为组内最小值、V8为组内最大值
分组替换数据框字段值
需求说明
现有按V7升序排列的grouped_df数据框,每个V4分组固定包含2行数据,需完成以下操作:
- 将每个
V4分组内的V7字段值全部替换为该分组V7的最小值 - 将每个
V4分组内的V8字段值全部替换为该分组V8的最大值
原始数据
df <- structure(list(V1 = c("chr9", "chr9", "chr1", "chr1", "chr2", "chr2"), V2 = c(130714314L, 130883963L, 179107712L, 179229235L, 157737525L, 157799421L), V3 = c(130714460L, 130885688L, 179109446L, 179229402L, 157737670L, 157799498L), V4 = c("ABL1", "ABL1", "ABL2", "ABL2", "ACVR1", "ACVR1"), V5 = c(0L, 0L, 0L, 0L, 0L, 0L), V6 = c(".", ".", ".", ".", ".", "."), V7 = c(130714314L, 130883963L, 179107712L, 179229235L, 157737525L, 157799421L), V8 = c(130714460L, 130885688L, 179109446L, 179229402L, 157737670L, 157799498L), V9 = c(0L, 0L, 0L, 0L, 0L, 0L), V10 = c(1L, 1L, 1L, 1L, 1L, 1L), V11 = c("146,", "1725,", "1734,", "167,", "145,", "77,"), V12 = c("0,", "0,", "0,", "0,", "0,", "0,")), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list( V4 = c("ABL1", "ABL2", "ACVR1"), .rows = structure(list(1:2, 3:4, 5:6), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -3L), .drop = TRUE))
期望输出
# A tibble: 6 × 12 # Groups: V4 [3] V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 <chr> <int> <int> <chr> <int> <chr> <int> <int> <int> <int> <chr> <chr> 1 chr9 130714314 130714460 ABL1 0 . 130714314 130885688 0 1 146, 0, 2 chr9 130883963 130885688 ABL1 0 . 130714314 130885688 0 1 1725, 0, 3 chr1 179107712 179109446 ABL2 0 . 179107712 179229402 0 1 1734, 0, 4 chr1 179229235 179229402 ABL2 0 . 179107712 179229402 0 1 167, 0, 5 chr2 157737525 157737670 ACVR1 0 . 157737525 157799498 0 1 145, 0, 6 chr2 157799421 157799498 ACVR1 0 . 157737525 157799498 0 1 77, 0,
现有尝试
已尝试通过以下代码获取分组内V7的最小值,但无法同时处理V8的最大值:
df %>% dplyr::group_by(V4) %>% dplyr::slice(which.min(V7))
备选思路考虑使用lag()/lead()函数,但未找到可行方案。
解决方案
方法一:使用dplyr的mutate结合min/max(通用方案)
直接在分组内计算V7的最小值和V8的最大值,替换原字段,适用于任意行数的分组:
library(dplyr) df_processed <- df %>% group_by(V4) %>% mutate( V7 = min(V7, na.rm = TRUE), V8 = max(V8, na.rm = TRUE) ) %>% ungroup() %>% # 若需保留分组可移除该行 group_by(V4) # 恢复分组结构(可选)
方法二:利用固定2行分组的特点使用lag/lead
由于数据已按V7升序排列,每个分组的第一行V7即为最小值;而V8的最大值在分组的第二行,因此可以用lead()获取第二行的V8值,或lag()获取第一行的V7值:
library(dplyr) df_processed <- df %>% group_by(V4) %>% mutate( V7 = first(V7), # 或 V7 = lag(V7, default = first(V7)) V8 = last(V8) # 或 V8 = lead(V8, default = last(V8)) ) %>% ungroup() %>% # 可选:移除分组 group_by(V4) # 可选:恢复分组结构
以上两种方法均可得到符合需求的输出结果。
内容的提问来源于stack exchange,提问作者user2300940
相关产品推荐
相关产品推荐

