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

编写R函数基于data frame列生成数值列却仅返回NA值的问题

问题分析与解决方法

问题根源

你写的函数里,传入的col1和col2是列名的字符串(比如"c1"),但在mutate中直接使用col1时,R会把它当成普通字符串变量,而不是引用数据框里的对应列。比如col1的值是"c1",拿"c1"和"Y"比较永远不相等,所以case_when返回NA。

修正方案

方案1:使用.data代词(dplyr推荐写法)

通过.data[[col1]]直接引用数据框中对应列名的列,适合传入字符串格式的列名:

library(dplyr)

d3 <- data.frame(c1 = c("Y", "N"), c2 = c("Y", "N"))

fun <- function(df1, col1, col2){
  df1 <- df1 %>% mutate(c3 = case_when(.data[[col1]] == "Y" ~ 1, .data[[col1]] == "N" ~ 0))
  df1 <- df1 %>% mutate(c4 = case_when(.data[[col2]] == "Y" ~ 2, .data[[col2]] == "N" ~ -1))
  return(df1)
}

d4 <- fun(d3, "c1", "c2")
head(d4)

方案2:使用整洁评估{{}}

如果调用函数时不想给列名加引号,直接传列名对象,可以用{{}}来捕获列名:

library(dplyr)

d3 <- data.frame(c1 = c("Y", "N"), c2 = c("Y", "N"))

fun <- function(df1, col1, col2){
  df1 <- df1 %>% mutate(c3 = case_when({{col1}} == "Y" ~ 1, {{col1}} == "N" ~ 0))
  df1 <- df1 %>% mutate(c4 = case_when({{col2}} == "Y" ~ 2, {{col2}} == "N" ~ -1))
  return(df1)
}

d4 <- fun(d3, c1, c2) # 此处直接传列名,无需加引号
head(d4)

方案3:使用sym()与!!解析字符串列名

这是早期dplyr版本的写法,通过将字符串转为符号,再用!!强制解析:

library(dplyr)
library(rlang) # 需要加载rlang包

d3 <- data.frame(c1 = c("Y", "N"), c2 = c("Y", "N"))

fun <- function(df1, col1, col2){
  col1_sym <- sym(col1)
  col2_sym <- sym(col2)
  df1 <- df1 %>% mutate(c3 = case_when(!!col1_sym == "Y" ~ 1, !!col1_sym == "N" ~ 0))
  df1 <- df1 %>% mutate(c4 = case_when(!!col2_sym == "Y" ~ 2, !!col2_sym == "N" ~ -1))
  return(df1)
}

d4 <- fun(d3, "c1", "c2")
head(d4)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:06:35