基于其他列条件替换分组内列NA值,保留指定非NA值(R语言)
解决方案
下面分别用tidyverse、data.table和base R三种方式实现需求,核心逻辑都是按Group_Name分组,将Value_1中的NA替换为同组内非NA且不等于567的有效值,同时保留原有的567值。
1. tidyverse 方案
library(dplyr) # 构造原始数据 df <- tibble( Group_Name = c("A", "A", "A"), Value_1 = c(NA, 12345, 567), Status = c(NA, "Active", NA) ) # 处理数据 df_processed <- df %>% group_by(Group_Name) %>% mutate( Value_1 = case_when( is.na(Value_1) ~ first(Value_1[!is.na(Value_1) & Value_1 != 567]), TRUE ~ Value_1 ) ) %>% ungroup() # 查看结果 df_processed
逻辑说明:按Group_Name分组后,用case_when做条件判断——如果Value_1是NA,就取同组内Value_1不为NA且不等于567的第一个有效值;其他情况直接保留原值,确保567不会被修改。
2. data.table 方案
library(data.table) # 构造原始数据 dt <- data.table( Group_Name = c("A", "A", "A"), Value_1 = c(NA, 12345, 567), Status = c(NA, "Active", NA) ) # 处理数据 dt_processed <- dt[, Value_1 := ifelse(is.na(Value_1), first(Value_1[!is.na(Value_1) & Value_1 != 567]), Value_1), by = Group_Name ] # 查看结果 dt_processed
逻辑说明:以Group_Name为分组键,用ifelse快速替换NA值——当Value_1是NA时,填充同组内符合条件的有效值;非NA值直接保留,567不受影响。
3. base R 方案
# 构造原始数据 df_base <- data.frame( Group_Name = c("A", "A", "A"), Value_1 = c(NA, 12345, 567), Status = c(NA, "Active", NA) ) # 处理数据 df_base_processed <- do.call(rbind, lapply(split(df_base, df_base$Group_Name), function(x) { # 找到同组内要填充的有效值 fill_val <- x$Value_1[!is.na(x$Value_1) & x$Value_1 != 567][1] # 替换NA x$Value_1[is.na(x$Value_1)] <- fill_val x })) # 重置行名 rownames(df_base_processed) <- NULL # 查看结果 df_base_processed
逻辑说明:先用split按Group_Name拆分数据框,对每个子数据框找到符合条件的填充值,再替换Value_1中的NA,最后用do.call(rbind)合并结果并重置行名。
内容的提问来源于stack exchange,提问作者emp88
相关产品推荐
相关产品推荐

