使用pmap()计算数据框多列行均值时结果异常的技术问询
为什么pmap()计算行均值得到的是vs列的值?
嘿,这个问题我之前也踩过类似的坑!让我给你拆解清楚背后的原因,以及pmap()的正确打开方式。
问题根源:pmap()的参数传递逻辑
你误解了pmap()的工作核心:pmap()会把你传入的列表中,每一行对应的元素作为独立参数传递给目标函数,而不是把它们打包成一个向量。
看你的代码:
mtcars %>% mutate(comp_var = pmap_dbl(list(vs, am, cyl), mean))
每一行的实际调用其实是:
mean(vs_row_value, am_row_value, cyl_row_value)
但mean()函数的定义是:
mean(x, trim = 0, na.rm = FALSE, ...)
这里的x是要计算均值的向量,后面的trim和na.rm是可选参数。所以你传入的am_row_value被当成了trim参数,cyl_row_value被当成了na.rm参数(注意:na.rm需要逻辑值,数值会被强制转换,比如6会变成TRUE)。
而vs_row_value是单个数值,对单个数值计算均值的结果就是它本身——这就是为什么你的comp_var等于vs列的值!
pmap()计算行均值的正确用法
要让pmap()正确计算多列的行均值,你需要把每行的多个值打包成一个向量再传给mean(),有几种简洁的写法:
1. 用公式语法和...合并参数
~是purrr里的公式简写,...代表所有传入的参数,把它们合并成向量后计算均值:
mtcars %>% mutate(comp_var = pmap_dbl(list(vs, am, cyl), ~mean(c(...)))) %>% select(comp_var, vs, am, cyl)
2. 显式定义函数合并参数
如果觉得公式语法不够直观,可以显式写一个小函数,把三个参数合并成向量:
mtcars %>% mutate(comp_var = pmap_dbl(list(vs, am, cyl), function(v, a, c) mean(c(v, a, c)))) %>% select(comp_var, vs, am, cyl)
3. 结合across()简化列选择
如果要处理的列很多,用across()一次性选择列,再传给pmap()更高效:
mtcars %>% mutate(comp_var = pmap_dbl(across(c(vs, am, cyl)), ~mean(c(...)))) %>% select(comp_var, vs, am, cyl)
额外补充:pmap()的适用场景
pmap()最适合的场景是:你的目标函数需要多个独立的参数。比如假设你有一个自定义函数:
calc_score <- function(vs, am, cyl) { vs * 0.2 + am * 0.3 + cyl * 0.5 }
这时候用pmap()就非常合适:
mtcars %>% mutate(score = pmap_dbl(list(vs, am, cyl), calc_score))
这里pmap()会把每行的vs、am、cyl分别作为三个参数传给calc_score(),完全符合函数的参数要求。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

