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

dplyr::mutate函数行为异常求助:添加binom检验p值失败

问题根源:binom.test不支持向量化输入

你遇到的问题核心在于两个函数的向量化能力本质不同:

  • 你的my_add函数依赖的是R原生的+运算符,它本身就是向量化设计——当传入两个向量时,会自动对每个位置的元素逐一计算,这也是它能在mutate里正常工作的原因。
  • 但binom.test是为单个样本设计的统计函数,它完全不支持向量输入。当你把向量传给它的x和n参数时,它不会逐个处理元素,反而会尝试把整个向量当作单个输入来处理,这就导致了两种异常:
    • 当数据框有2行时,binom.test可能只处理了第一组元素对,然后把结果重复返回(所以两行的p值完全一致);
    • 当数据框有3行时,binom.test无法处理长度为3的向量输入,直接抛出"incorrect length of 'x'"的错误。
解决方案:让函数支持向量化

有几种简单的方法可以解决这个问题,让你的my_binom函数能在mutate里正常工作:

方法1:用purrr::map2_dbl逐行计算

purrr包的map2_dbl可以对两个向量的对应元素逐一应用函数,并返回数值向量,完美适配mutate的需求:

library(dplyr)
library(purrr)

my_binom <- function(x, y) binom.test(x, y)$p.value
df <- data.frame(success=c(5,8,4), total=c(20,21,22))

df %>% mutate(p_value = map2_dbl(success, total, my_binom))
#>   success total   p_value
#> 1       5    20 0.0413881
#> 2       8    21 0.2427668
#> 3       4    22 0.0250576

方法2:用Vectorize包装函数

R内置的Vectorize函数可以快速把非向量化的函数包装成向量化版本,不需要额外依赖其他包:

my_binom_vec <- Vectorize(function(x, y) binom.test(x, y)$p.value)

df %>% mutate(p_value = my_binom_vec(success, total))
#>   success total   p_value
#> 1       5    20 0.0413881
#> 2       8    21 0.2427668
#> 3       4    22 0.0250576

方法3:用rowwise()让dplyr逐行处理

可以先用rowwise()把数据框转为逐行处理的模式,这样mutate就会对每一行单独调用函数,处理完记得取消逐行模式避免后续操作变慢:

df %>% 
  rowwise() %>% 
  mutate(p_value = my_binom(success, total)) %>%
  ungroup()
#> # A tibble: 3 × 3
#>   success total p_value
#>     <dbl> <dbl>   <dbl>
#> 1       5    20 0.0414 
#> 2       8    21 0.243  
#> 3       4    22 0.0251
额外说明

为什么2行的时候没有报错但返回错误结果?这是因为binom.test在接收向量时,会尝试用整个向量作为输入——比如当你传入x=c(5,8)和n=c(20,21)时,它其实是在做一个逻辑错误的二项式检验(把向量当作单一输入),而这个错误的输入刚好没有触发严格的长度检查,所以它把这个错误计算的结果重复填充到了每一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:53:50