You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在dplyr的case_when()中实现条件值替换的问题与解决

替换字符串中"inf"为对应子代ID的问题与解决方法

问题背景

有一组亲子对应关系数据集:

key <- data.frame(parent = c("ID1", "ID2", "ID3"), infant = c("ID4", "ID5", "ID6"))

另有一个行为数据集,其中用通用代码inf指代当前亲代对应的子代,亲代ID存储在id列:

df <- data.frame(time_point = 1:6, id = rep("ID2", 6), social1 = c(NA, NA, "inf", NA, NA, NA), social2 = c(NA, NA, NA, NA, NA, "inf"), social3 = c("inf", NA, NA, NA, NA, NA))

需求是将df中所有inf替换为key里对应亲代的子代ID。

初始尝试与报错

尝试用mutate+case_when实现替换时出现报错:

df %>% 
  mutate(social1 = case_when(
    grepl("inf", social1) ~ key[key$parent == id,]$infant,
    TRUE ~ social1
  ))

报错信息:

Error in mutate():
ℹ In argument: social1 = case_when(...).
Caused by error in case_when():
! Can't recycle ..1 (left) (size 6) to match ..1 (right) (size 2).

问题核心是在case_when的替换逻辑中引用其他列时,出现了向量长度不匹配的回收问题。

复杂场景更新

实际场景更复杂,inf可能与其他ID出现在同一字符串中:
更新后的数据集:

key <- data.frame(parent = c("ID1", "ID2", "ID3"), infant = c("ID4", "ID5", "ID6"))
df <- data.frame(time_point = 1:6, id = rep("ID2", 6), social1 = c(NA, NA, "inf ID7", NA, NA, NA), social2 = c(NA, NA, NA, NA, NA, "inf"), social3 = c("ID8 inf", NA, NA, NA, NA, NA))

尝试通过left_join关联亲子表后用gsub替换,出现警告:

df %>% 
  left_join(., key, by = c("id" = "parent")) %>%
  mutate(social1 = case_when(
    grepl("inf", social1) ~ gsub("inf",infant, social1),
    TRUE ~ social1
  ))

警告信息:

Warning message:
There was 1 warning in mutate().
ℹ In argument: social1 = case_when(...).
Caused by warning in gsub():
! argument 'replacement' has length > 1 and only the first element will be used

最终解决方案

在mutate前调用rowwise(),按行处理即可解决该问题,完整代码如下:

df %>% 
  left_join(., key, by = c("id" = "parent")) %>%
  rowwise() %>%
  mutate(
    social1 = case_when(
      grepl("inf", social1) ~ gsub("inf", infant, social1),
      TRUE ~ social1
    ),
    social2 = case_when(
      grepl("inf", social2) ~ gsub("inf", infant, social2),
      TRUE ~ social2
    ),
    social3 = case_when(
      grepl("inf", social3) ~ gsub("inf", infant, social3),
      TRUE ~ social3
    )
  ) %>%
  ungroup() # 处理完取消按行分组,避免后续操作受影响

该方法虽因逐行处理速度较慢,但能有效解决向量长度不匹配的问题,完成字符串中inf的替换。


内容的提问来源于stack exchange,提问作者gavago

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:02:39