参考重复分组值修改data.frame中etc1列数值的方法咨询
R 实现data.frame指定列修改的方法
核心思路
- 先对数据做分组:将
name、原始etc1值、etc2三者完全相同的行划为同一组,对应你需要修改的同批次行 - 给每个组内的行按顺序生成行号
- 按需给每行的
etc1赋值指定值即可
代码实现
1. 构造原始示例数据
library(dplyr) df <- tibble( name = c("A","A","A","B","B","B","A","A","A"), value = c(9,10,11,2,40,50,2,40,50), etc1 = c(1,1,1,1,1,1,4,4,4), etc2 = c("X","X","X","Y","Y","Y","X","X","X") )
2. 自定义指定值替换
如果每组的新值是提前定义好的,你可以用case_when直接匹配赋值:
# 先给每组内的行编序号 df <- df %>% group_by(name, etc1, etc2) %>% mutate(group_row = row_number()) %>% ungroup() # 按需求替换etc1的值 df <- df %>% mutate(etc1 = case_when( name == "A" & etc2 == "X" & etc1 == 1 ~ group_row, name == "B" & etc2 == "Y" & etc1 == 1 ~ group_row, name == "A" & etc2 == "X" & etc1 == 4 ~ case_match(group_row, 1~4, 2~5, 3~7) )) %>% select(-group_row) # 删除临时序号列
3. 固定规则自动生成新值
如果新值符合规则,比如每组以初始etc1值为起点依次递增1,不需要写死指定值,直接按组计算即可:
df %>% group_by(name, etc1, etc2) %>% mutate(etc1 = first(etc1) + row_number() - 1) %>% ungroup()
4. base R 实现方案
不需要依赖第三方包的实现方法:
# 生成分组ID df$group_id <- as.integer(interaction(df$name, df$etc1, df$etc2)) # 生成组内行号 df$row_in_group <- ave(df$group_id, df$group_id, FUN = seq_along) # 赋值替换 df$etc1 <- ifelse(df$group_id == 3 & df$row_in_group == 3, 7, df$etc1 + df$row_in_group - 1) # 删除临时列 df <- df[, !names(df) %in% c("group_id", "row_in_group")]
5. 批量替换方案
如果需要修改的组和值很多,可以先做映射表再左连接匹配,效率更高:
# 构造替换映射表 replace_map <- tibble( name = rep(c("A","B","A"), each=3), etc2 = rep(c("X","Y","X"), each=3), origin_etc1 = rep(c(1,1,4), each=3), row_in_group = rep(1:3, 3), new_etc1 = c(1,2,3,1,2,3,4,5,7) ) # 左连接替换值 df %>% group_by(name, etc1, etc2) %>% mutate(row_in_group = row_number(), origin_etc1 = etc1) %>% ungroup() %>% left_join(replace_map, by = c("name", "etc2", "origin_etc1", "row_in_group")) %>% mutate(etc1 = new_etc1) %>% select(name, value, etc1, etc2)
内容的提问来源于stack exchange,提问作者Hadi Md Nor
相关产品推荐
相关产品推荐

