如何在R中通过遍历列表名称程序化更新列表元素?
在R中通过遍历列表名称程序化更新列表元素的实现方法
我需要在R中通过遍历列表名称来程序化更新列表元素,是否可以使用非标准求值(Non-Standard Evaluation,NSE)或其他方法实现?
最小示例伪代码
x = list(a=1) y = list(a=3) for(i in c("x", "y")){ i[["a"]] <- 10 }
预期结果
x[["a"]] == 10 # 应返回 TRUE y[["a"]] == 10 # 应返回 TRUE
可行实现方法
方法1:直接操作环境(无副本高效修改)
你找到的这种方法可以直接修改环境中的列表对象,避免产生副本,效率更高:
x = list(a=1) y = list(a=3) .env = pryr::where("x") for(i in c("x", "y")){ .env[[i]][["a"]] <- 10 }
原理:pryr::where("x")获取列表x所在的环境,随后通过环境索引直接定位并修改目标列表的元素。
方法2:结合get与assign(常规副本式修改)
这是最常用的常规方法,适合处理小型列表:
x = list(a=1) y = list(a=3) for(i in c("x", "y")){ temp_list <- get(i) temp_list[["a"]] <- 10 assign(i, temp_list) }
原理:先用get获取对应名称的列表,修改后再用assign将修改后的列表放回原环境,缺点是会产生临时副本。
方法3:非标准求值(NSE)实现
利用rlang包的工具可以实现NSE方式的修改:
library(rlang) x = list(a=1) y = list(a=3) for(i in c("x", "y")){ obj_symbol <- sym(i) eval_tidy(expr(!!obj_symbol[["a"]] <- 10)) }
原理:将字符串形式的列表名转换为符号对象,用expr构建赋值表达式,最后通过eval_tidy执行表达式完成修改。
验证结果
执行任意一种方法后,运行以下代码验证:
x[["a"]] == 10 y[["a"]] == 10
两者都会返回TRUE,符合预期。
内容的提问来源于stack exchange,提问作者GitHunter0
相关产品推荐
相关产品推荐

