如何用R的apply系列函数同时为多个变量赋值?
问题解答
你的需求是从列表li中找到foo值最小的元素,同时记录其对应的索引。下面针对你的问题逐一说明:
关于apply/lapply的适用性
apply系列函数(包括lapply)的设计核心是对每个元素做独立处理并返回结果集合,属于无状态迭代——每次迭代不会保留上一次的计算状态(比如你需要持续更新的best_foo和best_i)。硬要用apply/lapply实现你的需求不仅代码冗余,效率也未必优于原生for循环,甚至可能更差,因此并不推荐。
最优实现:向量化操作
在R中,向量化操作是效率最高的处理方式,完全可以跳过循环或apply,直接一步完成需求:
# 提取列表中所有元素的foo值,转为向量 foo_values <- sapply(li, function(x) x$foo) # 找到最小值对应的索引 best_i <- which.min(foo_values) # 获取最小的foo值 best_foo <- foo_values[best_i]
这个方案利用R的底层向量化优化,代码简洁且性能远高于迭代类操作。
若非要用apply类函数实现(不推荐)
如果坚持要用lapply模拟你的循环逻辑,只能通过全局变量传递状态,写法繁琐且不优雅:
# 初始化状态容器 state <- list(best_foo = Inf, best_i = NA) # 用lapply遍历索引并更新状态 invisible(lapply(1:length(li), function(i) { current_foo <- li[[i]]$foo if (current_foo < state$best_foo) { # 用<<-修改全局环境中的状态变量 state$best_foo <<- current_foo state$best_i <<- i } })) # 提取最终结果 best_foo <- state$best_foo best_i <- state$best_i
这种写法依赖全局变量修改,代码可读性差,效率也不如原生for循环,完全没必要采用。
补充:关于R中for循环的效率误区
现在的R版本(3.4+)对for循环做了大量优化,只要不在循环内频繁创建大对象,简单for循环的效率并不会比apply差太多。但向量化操作始终是R的最优选择,优先考虑向量化,而非盲目替换for循环为apply。
内容的提问来源于stack exchange,提问作者hantan
相关产品推荐
相关产品推荐

