如何对数据框每行应用binom.test?代码报错求助排查
我明白你现在卡在怎么给数据框每行跑binom.test的问题上了——试过好几种函数都报unused argument错误,确实挺闹心的。咱们一步步来拆解问题,找到可行的方案,包括你熟悉的plyr替代法,还有tidyverse的现代写法。
先说说你报错的核心原因
binom.test的核心参数是x(成功次数)、n(总试验数),可选参数是p(原假设的成功概率)。你之前用mapply/pmap出错,大概率是参数映射不匹配:要么数据框的列名和函数参数名没对应上,要么传递参数时没把每行的元素正确分配给binom.test的对应参数。
解决方案1:用你熟悉的plyr包mdply(最省心的复古写法)
既然你之前用这个成功过,咱们先从这个入手,确保逻辑清晰:
假设你的数据框df有三列:success(成功数)、total(总试验数)、hypo_p(原假设概率),代码可以这么写:
library(plyr) # 对每行应用binom.test,并提取需要的结果 test_results <- mdply(df, function(success, total, hypo_p) { # 调用binom.test,参数和列名一一对应 binom_result <- binom.test(x = success, n = total, p = hypo_p) # 把结果整理成数据框,方便后续合并 data.frame( p_value = binom_result$p.value, conf_low = binom_result$conf.int[1], conf_high = binom_result$conf.int[2], estimate = binom_result$estimate ) })
mdply的优势就是自动把数据框的每行拆成参数,只要你的自定义函数参数名和数据框列名完全匹配,就不会有参数传递错误。
解决方案2:用purrr的pmap(tidyverse现代写法)
你之前用pmap报错,大概率是没把参数映射做对。试试这种写法:
library(purrr) library(dplyr) test_results <- df %>% # 用pmap遍历每行,参数名和列名对应 mutate(binom_output = pmap(., function(success, total, hypo_p) { binom.test(x = success, n = total, p = hypo_p) })) %>% # 从binom_output里提取需要的结果,转成单独的列 mutate( p_value = map_dbl(binom_output, "p.value"), conf_low = map_dbl(binom_output, ~ .x$conf.int[1]), conf_high = map_dbl(binom_output, ~ .x$conf.int[2]), estimate = map_dbl(binom_output, "estimate") ) %>% # 删掉中间的列表列 select(-binom_output)
这里的关键是pmap(., ...)里的.代表整个数据框,自定义函数的参数名必须和数据框列名完全一致,pmap才会把每行的对应值传给正确的参数。
解决方案3:用mapply的正确打开方式
之前用mapply出错,可能是没把列单独传递,或者没关自动简化。试试这个写法:
# 用mapply传递每一列作为参数,关闭自动简化 result_list <- mapply( function(x, n, p) binom.test(x = x, n = n, p = p), x = df$success, n = df$total, p = df$hypo_p, SIMPLIFY = FALSE ) # 把结果列表转成数据框 result_df <- do.call(rbind, lapply(result_list, function(res) { data.frame( p_value = res$p.value, conf_low = res$conf.int[1], conf_high = res$conf.int[2], estimate = res$estimate ) })) # 和原数据框合并 final_df <- cbind(df, result_df)
这里必须明确指定每个参数对应的列,而且SIMPLIFY = FALSE要打开,不然mapply会把结果自动简化成矩阵,导致后续提取信息出错。
最后再提几个避坑点
- 参数名必须严格对应:如果你的数据框列名是
x_num而不是x,那自定义函数里的参数也要写成x_num,或者在调用binom.test时明确指定x = x_num。 - 不要直接传整个数据框给mapply:mapply默认会把数据框的列作为整体传递,而不是每行的元素,这是最容易触发
unused argument的原因。 - 提取结果时注意类型:
binom.test返回的是列表,用map_dbl/map_chr可以方便地把列表里的数值/字符提取成向量。
内容的提问来源于stack exchange,提问作者SKOR2
相关产品推荐
相关产品推荐

