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

使用purrr::map批量执行函数时出现non-numeric argument错误求助

用map批量执行自定义统计函数时出现non-numeric参数错误

我需要用map函数对指定列批量生成汇总统计,单独调用自定义函数正常,但批量执行时触发non-numeric argument to mathematical function错误,具体代码和报错如下:

自定义统计函数

sumtab_ce_dt_ow_test <- function (df, depvar, treatvar)
{
  require(dplyr, kableExtra)
  df %>% dplyr::ungroup() %>%
    mutate({{depvar}} := as.numeric({{depvar}})) %>% 
    dplyr::filter(!is.na({{depvar}})) %>%
    group_by({{treatvar}}) %>%
    dplyr::summarize(
      N = n(),
      Med = round(median({{depvar}}, na.rm = T), 2)
    ) %>%
    arrange({{treatvar}})
}

示例数据

my_tibble <- tibble(
  rownumber = 1:100,
  a = sample(1:5, 100, replace = TRUE),
  b = sample(1:5, 100, replace = TRUE),
  c = sample(1:5, 100, replace = TRUE),
  phase = sample(c("before", "after"), 100, replace = TRUE),
) %>% 
  mutate(
    across(
      c(a, b, c),
      factor,
      levels = 1:5,
      labels = c("Strongly agree", "Agree", "Neutral", "Disagree", "Strongly disagree")
    )
  )

单独调用函数正常

my_tibble %>% sumtab_ce_dt_ow_test(depvar = a, treatvar = phase)
my_tibble %>% sumtab_ce_dt_ow_test(depvar = b, treatvar = phase)
my_tibble %>% sumtab_ce_dt_ow_test(depvar = c, treatvar = phase)

批量map调用报错代码

library(rlang)

response_texts <- c("Name 1", "name 2", "blah")
depvars <- c("a", "b", "c")
my_tibble <- my_tibble %>%  mutate(across(all_of(depvars), ~ as.numeric(.x)))

results <- map2_df(depvars, response_texts, function(depvar, response_text) {
  depvar <- enquo(depvar)
  my_tibble %>%
    sumtab_ce_dt_ow_test(depvar = !!depvar, treatvar = phase) %>%
    mutate(response = response_text)
})

报错信息

Error in `dplyr::summarize()`:
! Problem while computing `Med = round(median("a", na.rm = T), 2)`.
ℹ The error occurred in group 1: phase = "after".
Caused by error in `round()`:
! non-numeric argument to mathematical function 
Backtrace:
  1. purrr::map2_df(...)
 10. dplyr:::summarise.grouped_df(...)
 11. dplyr:::summarise_cols(.data, dplyr_quosures(...), caller_env = caller_env())
 13. dplyr:::map(quosures, summarise_eval_one, mask = mask)
 14. base::lapply(.x, .f, ...)
 15. dplyr (local) FUN(X[[i]], ...)
 16. mask$eval_all_summarise(quo)
Called from: signal_abort(cnd, .file)
Warning message:
Problem while computing `a = as.numeric("a")`.
ℹ NAs introduced by coercion 

问题原因与解决办法

  • 核心问题:enquo(depvar)会把传入的字符串(比如"a")转换成引用字符串本身的表达式,而非引用数据框中的列。函数中{{depvar}}实际调用的是字符串值"a",导致as.numeric("a")产生NA,后续median("a")触发非数值参数错误。
  • 解决方法:直接使用.data代词或sym()+!!解析字符串列名,无需enquo:

修正后的批量调用代码

library(rlang)
library(purrr)

response_texts <- c("Name 1", "name 2", "blah")
depvars <- c("a", "b", "c")
my_tibble <- my_tibble %>%  mutate(across(all_of(depvars), ~ as.numeric(.x)))

# 方法1:使用.data代词
results <- map2_df(depvars, response_texts, function(depvar, response_text) {
  my_tibble %>%
    sumtab_ce_dt_ow_test(depvar = .data[[depvar]], treatvar = phase) %>%
    mutate(response = response_text)
})

# 方法2:使用sym转换为符号后解引用
# results <- map2_df(depvars, response_texts, function(depvar, response_text) {
#   depvar_sym <- sym(depvar)
#   my_tibble %>%
#     sumtab_ce_dt_ow_test(depvar = !!depvar_sym, treatvar = phase) %>%
#     mutate(response = response_text)
# })

可选:修改函数兼容两种输入方式

如果希望函数同时支持裸列名和字符串列名,可调整函数代码:

sumtab_ce_dt_ow_test <- function (df, depvar, treatvar)
{
  require(dplyr, kableExtra)
  depvar <- enquo(depvar)
  # 若传入字符串,转换为对应列的符号
  if (is.character(depvar[[2]])) {
    depvar <- sym(depvar[[2]])
  }
  treatvar <- enquo(treatvar)
  
  df %>% dplyr::ungroup() %>%
    mutate(!!depvar := as.numeric(!!depvar)) %>% 
    dplyr::filter(!is.na(!!depvar)) %>%
    group_by(!!treatvar) %>%
    dplyr::summarize(
      N = n(),
      Med = round(median(!!depvar, na.rm = T), 2)
    ) %>%
    arrange(!!treatvar)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:50:50