为何purrr::map的两段代码输出不同?基于官方文档的疑问
问题
根据purrr包map函数的文档说明(若为字符向量、数值向量或列表,将被转换为提取器函数),以下两段代码难道不应该产生相同的输出吗?
第一段代码:
map(1:3, function(x){x[runif(2)]}) # [[1]] # integer(0) # # [[2]] # integer(0) # # [[3]] # integer(0)
第二段代码:
map(1:3, runif(2)) # [[1]] # NULL # # [[2]] # NULL # # [[3]] # NULL
想了解为何这两段代码的输出存在差异。
解答
核心差异在于**runif(2)的执行时机以及map对第二个参数的处理逻辑**:
第一段代码的逻辑
你传入的是匿名函数function(x){x[runif(2)]},map会对1:3中的每个元素(1、2、3)分别执行这个函数:- 每次迭代时,都会重新调用
runif(2)生成两个0到1之间的随机数 - 用这两个数作为索引去取单个整数x的元素,但R中向量的索引必须是正整数,0到1的数会被视为无效索引,因此返回
integer(0)(空整数向量)
- 每次迭代时,都会重新调用
第二段代码的逻辑
你直接传入runif(2),这行代码会先于map执行,生成一个固定的双元素数值向量(比如c(0.3, 0.7))。
根据map的规则,数值向量会被转换成提取器函数,等价于function(x) pluck(x, 这个预先生成的向量)。
同样,因为预先生成的向量元素是0到1的无效索引,无法从单个整数x中提取到任何元素,所以返回NULL。
简单来说:
- 第一段是每次迭代都重新生成随机索引,无效索引返回空整数向量
- 第二段是先生成固定的无效索引向量,再用提取器逻辑尝试取值,取不到就返回NULL
内容的提问来源于stack exchange,提问作者Abbas
相关产品推荐
相关产品推荐

