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

基于值标签构建可在dplyr::mutate/across运行的二分转换函数

解决方案

针对你的需求,我们可以重构make_dicho()函数,使其适配dplyr的管道环境,无需手动传入数据框,同时完美支持across()批量处理变量。核心思路是利用rlang的tidy eval工具自动识别运行环境,同时兼容单独调用、mutate()调用和across()调用三种场景。

最终函数代码

library(dplyr)
library(rlang)
library(labelled)
library(stringr)

make_dicho <- function(var, df = NULL) {
  # 处理三种调用场景:单独传入df、mutate中调用、across中传入向量
  if (!is.null(df)) {
    # 单独调用时,从指定数据框提取变量
    var_name <- as_name(enexpr(var))
    var_vec <- df[[var_name]]
  } else if (is_symbol(enexpr(var))) {
    # 在mutate管道中,自动获取当前数据框的变量
    var_vec <- cur_data()[[as_name(enexpr(var))]]
  } else {
    # 在across中,直接处理传入的带标签向量
    var_vec <- var
  }
  
  # 检查变量是否有值标签
  val_labels <- val_labels(var_vec)
  if (is.null(val_labels)) {
    stop("目标变量没有值标签,请先使用labelled包添加标签后再处理。")
  }
  
  # 反转值标签映射,方便通过数值匹配对应的文本标签
  label_map <- names(val_labels)
  names(label_map) <- val_labels
  
  # 将数值转换为文本标签,再进行二分判断
  label_text <- label_map[as.character(var_vec)]
  case_when(
    str_detect(label_text, regex("agree", ignore_case = TRUE)) ~ "Agree",
    str_detect(label_text, regex("disagree", ignore_case = TRUE)) ~ "Disagree",
    TRUE ~ NA_character_
  )
}

场景测试

1. 单独调用函数

make_dicho(x, df = data)
# 输出:[1] "Disagree" "Disagree" "Agree"    "Agree"

2. 在mutate()中调用(无需传入.)

data %>% 
  mutate(new_x = make_dicho(x))

3. 在across()中批量处理变量

data %>% 
  mutate(
    across(x:z, make_dicho, .names = "new_{col}")
  )

关键改进点

  1. 自动识别数据环境:

    • 在mutate()中调用时,通过cur_data()自动获取当前管道中的数据框,无需手动传入.
    • 兼容单独调用场景,通过可选的df参数指定数据框
  2. 适配across()运行逻辑:

    • 判断输入类型:如果是across()传入的带标签向量,直接处理;如果是变量名,则从数据框提取变量
    • 基于值标签文本进行二分,不受量表点数(4/6点)限制,只要标签包含"agree"/"disagree"即可正确分类
  3. 鲁棒性增强:

    • 添加值标签检查,避免无标签变量导致的错误
    • 使用不区分大小写的正则匹配,兼容不同格式的标签文本(如"Strongly Agree"或"strongly agree")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 20:51:26