R语言按分组替换缺失值:组内全空时用另一列对应值替换
问题原因
你代码出错是R基础函数ifelse()的特性导致的:ifelse()的返回值长度和判断条件的长度完全一致。你的判断条件all(is.na(val2))是每个分组内仅返回1个的逻辑值,所以结果只会取val1的第一个元素循环填充整个分组,不符合需求。
修正方案
直接用R原生的分支判断结构if(){}else{}替代ifelse()即可,dplyr分组环境下会对每个分组单独执行全局判断:
library(tidyverse) df <- tibble(ID = c("A", "A", "A", "B", "B", "B"), val1 = c(1,2,3,4,5,6), val2 = c(NA, NA, NA, NA, 2, 3)) # 修正后代码 df %>% group_by(ID) %>% mutate(val2 = if (all(is.na(val2))) val1 else val2)
运行结果
# A tibble: 6 × 3 # Groups: ID [2] ID val1 val2 <chr> <dbl> <dbl> 1 A 1 1 2 A 2 2 3 A 3 3 4 B 4 NA 5 B 5 2 6 B 6 3
原理说明
dplyr分组操作中,mutate内的if(){}else{}会针对每个分组单独执行:先判断当前分组的val2是否全为缺失值,是就返回该分组整列val1作为新的val2,否则直接返回原有val2,完全匹配需求逻辑。
内容的提问来源于stack exchange,提问作者Hakki
相关产品推荐
相关产品推荐

