R中仅为Problem列值为D的行合并数据框填充服务时间
问题:为数据框特定行填充推导的服务时间
我在R中有两个数据框:
数据框df_1(相关列如下):
Problem |Service_Time | Imputed_Problem ---------------------------------------------- A | 3.5 | NA B | 1.6 | NA C | 2.8 | NA D | NA | B
当Problem列值为D时,表示患者未就诊就离开,无登记问题及服务时间。已基于人群中各问题的出现概率,为所有Problem==D的行随机分配A/B/C作为Imputed_Problem。
需求:
- 真实问题的行,
Imputed_Service_Time沿用原Service_Time值 Problem为D的行,将df_2中对应Imputed_Problem的平均服务时间填入Imputed_Service_Time
数据框df_2(存储各问题的平均服务时间):
Problem | Average_Service_Time ---------------------- A | 3.2 B | 4.2 C | 1.7
我已在df_1中创建Imputed_Service_Time列并复制自Service_Time,尝试了以下代码:
merged_df <- merge(df_1, df_2, by.x = "Imputed_Problem", by.y = "Problem", all.x = TRUE) merged_df$Imputed_Service_Time <- ifelse(is.na(merged_df$Service_Time), merged_df$Average_Service_Time, merged_df$Service_Time)
但出现错误:
Error in ans[ypos] <- rep(yes, length.out = len)[ypos] : replacement has length zero In addition: Warning message: In rep(yes, length.out = len) : 'x' is NULL so the result will be NULL
解决方案
方法1:Base R 直接匹配替换
无需合并整个数据框,精准定位目标行后完成替换:
# 确保Imputed_Service_Time列已创建 df_1$Imputed_Service_Time <- df_1$Service_Time # 筛选出Problem为D的行索引 d_row_indices <- df_1$Problem == "D" # 匹配Imputed_Problem与df_2的Problem,提取对应平均服务时间并替换 df_1$Imputed_Service_Time[d_row_indices] <- df_2$Average_Service_Time[ match(df_1$Imputed_Problem[d_row_indices], df_2$Problem) ]
方法2:使用dplyr(tidyverse风格)
通过管道操作更直观地完成数据关联与替换:
library(dplyr) df_1 <- df_1 %>% # 关联df_2,用Imputed_Problem匹配Problem left_join(df_2, by = c("Imputed_Problem" = "Problem")) %>% # 按规则填充Imputed_Service_Time mutate(Imputed_Service_Time = case_when( Problem == "D" ~ Average_Service_Time, TRUE ~ Service_Time )) %>% # 可选:移除临时关联的平均时间列 select(-Average_Service_Time)
错误原因说明
原代码报错是因为合并后,非D行的Imputed_Problem为NA,导致Average_Service_Time对应位置也为NA。当ifelse处理时,若Service_Time非NA则正常,但当Service_Time为NA时,Average_Service_Time可能出现空值或长度不匹配的情况,触发替换错误。上述方案直接针对D行操作,避免了不必要的全表合并与空值干扰。
内容的提问来源于stack exchange,提问作者Emma541
相关产品推荐
相关产品推荐

