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

如何使用tidyverse的cur_column()合并多列(SDQ量表场景)

合并SDQ量表不同年龄段条目列的解决方案

我有SDQ(长处与困难量表)的25个条目,需要将每个条目的2to4yrs版本列与5to17yrs版本列合并,最终保留2to4yrs列名,用5to17yrs列的非NA值填补对应2to4yrs列的NA值。

示例数据

library(tidyverse)
df <- data.frame(
  sdq2to4yrs_item1 = c(1, NA, NA),
  sdq5to17yrs_item1 = c(NA, NA, 2),
  sdq2to4yrs_item2 = c(2, 2, NA),
  sdq5to17yrs_item2 = c(1, 2, 3)
)

df
#>   sdq2to4yrs_item1 sdq5to17yrs_item1 sdq2to4yrs_item2 sdq5to17yrs_item2
#> 1                1                NA                2                 1
#> 2               NA                NA                2                 2
#> 3               NA                 2               NA                 3

期望结果

data.frame(
  sdq2to4yrs_item1 = c(1, NA, 2),
  sdq2to4yrs_item2 = c(2, 2, 3)
)
#>   sdq2to4yrs_item1 sdq2to4yrs_item2
#> 1                1                2
#> 2               NA                2
#> 3                2                3

报错代码

尝试用以下代码实现但触发递归求值错误:

df %>%
  mutate(
    across(
      matches("2to4yrs"),
      ~ coalesce(
        !!!select(., matches(
          cur_column() %>% str_remove(".*yrs_")
        )
        )
      )
    )
  )
#> Error in local_error_context(dots = dots, .index = i, mask = mask): promise already under evaluation: recursive default argument reference or earlier problems?

解决方案

报错原因

原代码在coalesce中使用!!!select(., ...)时,会递归引用正在修改的数据框,触发promise求值冲突,导致报错。

方案1:长格式转换法(适合批量处理)

先转长格式按条目分组合并,再转回宽格式:

df %>%
  pivot_longer(
    everything(),
    names_to = c("age_group", "item"),
    names_pattern = "sdq(.*)_item(\\d+)",
    values_to = "value"
  ) %>%
  group_by(item) %>%
  summarise(
    value = coalesce(value[age_group == "2to4yrs"], value[age_group == "5to17yrs"])
  ) %>%
  pivot_wider(
    names_from = item,
    names_prefix = "sdq2to4yrs_item",
    values_from = value
  )

方案2:直接匹配对应列(更简洁)

在across中提取条目编号,构造对应5to17yrs列名,直接合并:

df %>%
  mutate(
    across(matches("2to4yrs"), ~ {
      # 提取条目后缀(如item1、item2)
      item_suffix <- str_remove(cur_column(), "sdq2to4yrs_")
      # 构造对应5to17yrs列的列名
      target_col <- sym(str_c("sdq5to17yrs_", item_suffix))
      # 合并两列,保留非NA值
      coalesce(., !!target_col)
    })
  ) %>%
  # 可选:移除原5to17yrs列
  select(-matches("5to17yrs"))

运行上述任意方案均可得到期望结果。

内容的提问来源于stack exchange,提问作者its.me.adam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:36:33