英文:
How to pass a named argument stored in a string to list() in R
问题
如果我有一个字符串如下:
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)
更新
已经提供了许多解决方案,但似乎没有一个完全符合我的意思,当我说"如何将[一个字符串]传递给list()
"时。这是我的意思:
list(x = 'z', y = 1, some_function("x = 'a'"))
其中some_function
可以接受一个字符串,解析其中的表达式,然后将其评估,就像它只是传递给list()
的另一个命名对象一样。
英文:
If I have a string like:
s <- "x = 1"
how do I pass this to list()
and end up with a list with one element named "x" and equal to 1. Like this:
list(x = 1)
I tried:
list(eval(str2lang(s)))
I know one way to do this:
s2 <- strsplit(s, " = ")[[1]]
stats::setNames(list(s2[2]), s2[1])
I don't like the above solution, however, because it produces double and singles quotes if the value being assigned inside the list is already quoted:
s <- "x = 'a'"
s2 <- strsplit(s, " = ")[[1]]
lst1 <- stats::setNames(list(s2[2]), s2[1])
lst2 <- list(x = 'a')
all.equal(lst1, lst2)
Update
A number of solutions have been offered, but none seem to do quite what I had in mind when I say "how do I pass [a string] to list()
".
This is what I mean:
list(x = 'z', y = 1, some_function("x = 'a'"))
where some_function
can take a string, parse the expression inside, and then have it evaluated as if it were just another named object being passed to list()
.
答案1
得分: 2
f <- function(string){
a <- str2lang(string)
as.list(setNames(a[[3]], as.character(a[[2]])))
}
s1 <- "x = 'a'"
s <- "x = 1"
f(s)
#> $x
#> [1] 1
f(s1)
#> $x
#> [1] "a"
Created on 2023-02-09 with reprex v2.0.2;
Using eval
, you could do:
eval(str2lang(sprintf('list(%s)',s))
<details>
<summary>英文:</summary>
``` r
f <- function(string){
a <- str2lang(string)
as.list(setNames(a[[3]], as.character(a[[2]])))
}
s1 <- "x = 'a'"
s <- "x = 1"
f(s)
#> $x
#> [1] 1
f(s1)
#> $x
#> [1] "a"
<sup>Created on 2023-02-09 with reprex v2.0.2</sup>
Using eval
, you could do:
eval(str2lang(sprintf('list(%s)',s)))
答案2
得分: 1
s = "x = 1"
env <- new.env(parent = emptyenv())
env[["list"]] <- base::list
eval(str2lang(paste0("list(", s, ")")), env)
#> $x
#> [1] 1
英文:
s = "x = 1"
env <- new.env(parent = emptyenv())
env[["list"]] <- base::list
eval(str2lang(paste0("list(", s, ")")), env)
#> $x
#> [1] 1
The empty env
environment is in order to prevent running code other than "list".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论