purrr::map的对象索引提取功能是否过于魔法?其内部运行原理是什么
purrr 映射函数元素提取机制的运行逻辑
你提到的这种通过字符串/索引直接提取对象元素的“魔法”能力,本质是purrr对map*系列函数的.f参数做了自动适配处理,具体逻辑如下:
- 所有
map类函数接收到第二个参数(要应用的函数)时,会先判断参数类型:如果不是函数,会自动调用purrr::pluck()将其转换为元素提取函数 - 不同的非函数参数对应不同的提取规则:
- 传入字符串:按列表元素名提取对应值
- 传入整数:按列表元素的位置索引提取对应值
- 传入字符串/整数组成的向量:按顺序执行多层嵌套提取,比如传入
c("coefficients", "wt")就可以一步提取lm模型的wt变量回归系数
- 对应你的示例代码:
你用到的map_dbl(summary, "r.squared")完全等价于两种更直观的写法,效果完全一致:
# 手动写匿名函数提取 r2 = map_dbl(summary, ~ .x$r.squared) # 显式调用pluck提取 r2 = map_dbl(summary, pluck, "r.squared")
lm函数的summary返回值本身就是标准的命名列表结构,你可以执行str(summary(lm(mpg ~ wt, mtcars)))查看其结构,能看到顶层确实存在r.squared这个命名元素,所以可以直接通过字符串提取。
这种设计除了简化代码外,还有额外的容错优势:pluck提取不存在的元素时会返回NULL,你还可以通过.default参数指定缺失时的默认返回值,避免整个迭代直接报错。
内容的提问来源于stack exchange,提问作者dzegpi
相关产品推荐
相关产品推荐

