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

R语言tidyverse如何仅当分组无NA时判断组内是否存在值4

实现方案

你可以通过批量遍历分组前缀的方式实现需求,仅需少量代码即可适配任意数量的分组,无需手动逐个定义变量或生成中间标记列:

如果你的分组前缀是已知的,可以直接定义前缀列表:

library(tidyverse)
# 示例数据和你提供的一致
df <- data.frame(Subj = c("A", "B", "C", "D"),
                 Happy_1_Num = c(4,2,2,NA),
                 Happy_2_Num = c(4,2,2,1),
                 Happy_3_Num = c(1,NA,2,4),
                 Sad_1_Num = c(2,1,4,3),
                 Sad_2_Num = c(NA,1,2,4),
                 Sad_3_Num = c(4,2,2,1))

# 定义所有需要处理的分组前缀
group_prefix <- c("Happy", "Sad")

# 一步生成所有新变量
df <- df %>%
  mutate(
    across(all_of(group_prefix), 
           ~ case_when(
             # 分组内任意变量为NA则返回NA
             if_any(matches(paste0("^", cur_column(), "_.*_Num$")), is.na) ~ NA_real_,
             # 分组内任意变量为4则返回1
             if_any(matches(paste0("^", cur_column(), "_.*_Num$")), ~.x == 4) ~ 1,
             # 其余情况返回0
             .default = 0
           ),
           # 新变量命名规则
           .names = "{.col}_Any4")
  )

如果你的分组数量多、前缀不固定,可以自动从列名提取所有符合规则的前缀,无需手动填写:

# 自动提取所有符合 前缀_数字_Num 格式的列的前缀
group_prefix <- str_extract(names(df), "^.*(?=_[0-9]+_Num$)") %>% 
  na.omit() %>% 
  unique()

# 后续和上面的mutate代码完全一致
df <- df %>%
  mutate(
    across(all_of(group_prefix), 
           ~ case_when(
             if_any(matches(paste0("^", cur_column(), "_.*_Num$")), is.na) ~ NA_real_,
             if_any(matches(paste0("^", cur_column(), "_.*_Num$")), ~.x == 4) ~ 1,
             .default = 0
           ),
           .names = "{.col}_Any4")
  )

结果验证

运行后生成的Happy_Any4和Sad_Any4结果如下,完全符合规则要求:

SubjHappy_Any4Sad_Any4
A1NA
BNA0
C01
DNA1

原代码问题说明

最初的写法逻辑本身没有错误,问题出在多条件matches的兼容性上,部分dplyr版本对matches(A) & matches(B)的支持不稳定,合并为单个正则表达式matches("^前缀_.*_Num$")即可解决,配合批量遍历的写法可以大幅减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:06:01