如何在dplyr管道中使用uniroot函数求解方程根?
我明白你遇到的问题了——单独调用uniroot能算出想要的x值,但把它整合到dplyr管道里就卡壳了对吧?这主要是因为uniroot是面向单个数值的函数,而dplyr默认按向量批量处理,直接传整列的A值会导致不兼容;另外你用do的写法也没完全匹配它的使用逻辑。下面给你两种简洁可行的解决方案:
先准备好基础代码
首先确认我们的函数和数据集是正确的:
library(tibble) library(dplyr) myfunc <- function(x, y, A) {2 + A * x - y} mydat <- tribble( ~crop, ~year, ~A, "corn", 2011, 4, "corn", 2012, 8.5, "soy", 2011, 4.2 )
方案1:用rowwise()逐行处理
rowwise()会告诉dplyr对每一行单独执行操作,这样每行的A值会以单个数值的形式传给uniroot,完美匹配它的要求。最后别忘了用ungroup()取消行分组,避免影响后续操作:
mydat %>% rowwise() %>% mutate(x50 = uniroot(myfunc, y = 0.5, A = A, lower = 0, upper = 10, extendInt = "yes")$root) %>% ungroup()
方案2:用purrr::map_dbl遍历向量
如果你习惯用purrr工具包,map_dbl可以遍历A列的每个元素,对单个值调用uniroot并提取结果,最后返回一个数值向量直接作为新列:
library(purrr) mydat %>% mutate(x50 = map_dbl(A, ~ uniroot(myfunc, y = 0.5, A = .x, lower = 0, upper = 10, extendInt = "yes")$root))
为什么你的原始代码会失败?
- 第一种
mutate写法里用.$A,会把整个A列的向量传给uniroot的A参数,但myfunc里A需要是单个数值,向量和x(单个值)做运算会报错。 - 第二种
do的写法,默认会返回包含列表的tibble,你需要把结果整理成数据框才能和原表合并,写法会更繁琐,不如上面两种方案简洁。
运行上面的方案后,你会得到包含x50列的结果,比如第一行x50=-0.375,这和手动解方程2 + 4x - 0.5 = 0得到的x=(0.5-2)/4=-0.375完全一致。
内容的提问来源于stack exchange,提问作者Gina Nichols
相关产品推荐
相关产品推荐

