如何在R语言中将字符串形式的命名参数传入list()函数
R语言:将字符串形式的命名表达式转为list的命名参数
我有一个字符串,例如:
s <- "x = 1"
想要将其传入list()函数,得到包含名为"x"、值为1的元素的列表,等价于执行:
list(x = 1)
已尝试的方法
我试过下面的写法,但达不到预期效果:
list(eval(str2lang(s)))
我还知道一种实现方式,但并不满意:
s2 <- strsplit(s, " = ")[[1]] stats::setNames(list(s2[2]), s2[1])
这个方案的问题在于,当值本身带引号时,会保留多余的引号:
s <- "x = 'a'" s2 <- strsplit(s, " = ")[[1]] lst1 <- stats::setNames(list(s2[2]), s2[1]) lst2 <- list(x = 'a') all.equal(lst1, lst2) # 返回FALSE,因为lst1的x值是字符串"'a'"而非'a'
更新需求
目前的方案都不符合我的预期,我需要一个some_function,能直接在list()中使用,接收字符串并解析其中的表达式,让它的效果和直接传入命名参数完全一致,比如:
list(x = 'z', y = 1, some_function("x = 'a'"))
解决方案
可以编写一个函数,解析字符串为表达式后,提取参数名和对应的值并求值,返回一个单元素的命名列表,再结合rlang包的非标准求值语法!!!(展开列表元素作为命名参数):
library(rlang) parse_named_arg <- function(s) { # 将字符串转为R可识别的表达式 expr <- str2lang(s) # 提取参数名 arg_name <- as.character(expr[[2]]) # 求值得到参数值 arg_value <- eval(expr[[3]]) # 返回命名列表 structure(list(arg_value), names = arg_name) } # 使用示例 result <- list(x = 'z', y = 1, !!!parse_named_arg("x = 'a'")) print(result) # $x # [1] "a" # $y # [1] 1
如果不想依赖rlang,可以用c()合并列表来达到类似效果:
result <- c(list(x = 'z', y = 1), parse_named_arg("x = 'a'")) print(result)
原理说明
str2lang(s)将字符串转为R可识别的表达式(比如"x = 'a'"转为x = 'a')- 提取表达式的第二部分作为参数名(
expr[[2]]对应x),第三部分作为要求值的内容(expr[[3]]对应'a') - 通过
eval()对值部分求值,避免保留多余的引号 - 最后构造命名列表,再通过
!!!展开为list()的命名参数
内容的提问来源于stack exchange,提问作者Giovanni Colitti
相关产品推荐
相关产品推荐

