如何基于行号条件更新DataFrame(R语言dplyr实现)
简洁批量更新指定ID行的列值
我们以mpg数据集为例,先添加行号作为ID列:
DATA1 <- mpg DATA2 <- dplyr::mutate(DATA1, ID = row_number())
需求是基于ID值仅更新DATA2中的部分列,比如:
IF ID1 then manufacturer="Honda", cyl=6, year=2005,
IF ID2 then manufacturer="Toyota", class="sedan"
原来的方法通过多次嵌套mutate和ifelse实现,但代码过于冗长,不适用于涉及多行修改的大型数据集:
DATA3 <- DATA2 %>% mutate(manufacturer = ifelse(ID == 1, "Honda", manufacturer)) %>% mutate(cyl = ifelse(ID == 1, 6, cyl)) %>% mutate(year = ifelse(ID == 1, 2005, year)) DATA3 <- DATA2 %>% mutate(manufacturer = ifelse(ID == 2, "Toyota", manufacturer)) %>% mutate(class = ifelse(ID == 2, "sedan", class))
方法1:用case_when在单个mutate中批量处理
把同一ID的多列更新逻辑集中到一个mutate里,用case_when替代重复的ifelse,代码更简洁易维护:
library(dplyr) DATA3 <- DATA2 %>% mutate( manufacturer = case_when( ID == 1 ~ "Honda", ID == 2 ~ "Toyota", TRUE ~ manufacturer # 其他ID保持原数值 ), cyl = case_when( ID == 1 ~ 6, TRUE ~ cyl ), year = case_when( ID == 1 ~ 2005, TRUE ~ year ), class = case_when( ID == 2 ~ "sedan", TRUE ~ class ) )
方法2:创建更新规则表,通过连接实现批量更新(适合大量ID场景)
如果要更新的ID和列数量很多,先做一个更新规则表,再通过连接合并,用coalesce自动替换需要更新的值,未指定的列保留原值:
library(dplyr) # 定义更新规则:只填需要修改的ID和对应列,NA表示不修改该列 update_rules <- tibble( ID = c(1, 2), manufacturer = c("Honda", "Toyota"), cyl = c(6, NA), year = c(2005, NA), class = c(NA, "sedan") ) # 合并规则表并替换数值 DATA3 <- DATA2 %>% left_join(update_rules, by = "ID") %>% mutate( manufacturer = coalesce(manufacturer.y, manufacturer.x), cyl = coalesce(cyl.y, cyl.x), year = coalesce(year.y, year.x), class = coalesce(class.y, class.x) ) %>% select(-ends_with(".x"), -ends_with(".y")) # 删除合并产生的冗余列
内容的提问来源于stack exchange,提问作者user2596306
相关产品推荐
相关产品推荐

