如何将存储在字符串中的命名参数传递给R中的list()函数

huangapple go评论92阅读模式
英文:

How to pass a named argument stored in a string to list() in R

问题

如果我有一个字符串如下:

  1. s <- "x = 1"

如何将它传递给list(),并最终得到一个名为"x"且值为1的元素的列表,就像这样:

  1. list(x = 1)

我尝试过:

  1. list(eval(str2lang(s)))

我知道一种方法可以实现这个目标:

  1. s2 <- strsplit(s, " = ")[[1]]
  2. stats::setNames(list(s2[2]), s2[1])

然而,我不喜欢上面的解决方案,因为如果在列表中赋值的值已经带有引号,它会生成双引号和单引号:

  1. s <- "x = 'a'"
  2. s2 <- strsplit(s, " = ")[[1]]
  3. lst1 <- stats::setNames(list(s2[2]), s2[1])
  4. lst2 <- list(x = 'a')
  5. all.equal(lst1, lst2)

更新

已经提供了许多解决方案,但似乎没有一个完全符合我的意思,当我说"如何将[一个字符串]传递给list()"时。这是我的意思:

  1. list(x = 'z', y = 1, some_function("x = 'a'"))

其中some_function可以接受一个字符串,解析其中的表达式,然后将其评估,就像它只是传递给list()的另一个命名对象一样。

英文:

If I have a string like:

  1. 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:

  1. list(x = 1)

I tried:

  1. list(eval(str2lang(s)))

I know one way to do this:

  1. s2 <- strsplit(s, " = ")[[1]]
  2. 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:

  1. s <- "x = 'a'"
  2. s2 <- strsplit(s, " = ")[[1]]
  3. lst1 <- stats::setNames(list(s2[2]), s2[1])
  4. lst2 <- list(x = 'a')
  5. 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:

  1. 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

  1. f <- function(string){
  2. a <- str2lang(string)
  3. as.list(setNames(a[[3]], as.character(a[[2]])))
  4. }
  5. s1 <- "x = 'a'"
  6. s <- "x = 1"
  7. f(s)
  8. #> $x
  9. #> [1] 1
  10. f(s1)
  11. #> $x
  12. #> [1] "a"

Created on 2023-02-09 with reprex v2.0.2;

Using eval, you could do:

eval(str2lang(sprintf('list(%s)',s))

  1. <details>
  2. <summary>英文:</summary>
  3. ``` r
  4. f &lt;- function(string){
  5. a &lt;- str2lang(string)
  6. as.list(setNames(a[[3]], as.character(a[[2]])))
  7. }
  8. s1 &lt;- &quot;x = &#39;a&#39;&quot;
  9. s &lt;- &quot;x = 1&quot;
  10. f(s)
  11. #&gt; $x
  12. #&gt; [1] 1
  13. f(s1)
  14. #&gt; $x
  15. #&gt; [1] &quot;a&quot;

<sup>Created on 2023-02-09 with reprex v2.0.2</sup>

Using eval, you could do:

  1. eval(str2lang(sprintf(&#39;list(%s)&#39;,s)))

答案2

得分: 1

  1. s = "x = 1"
  2. env <- new.env(parent = emptyenv())
  3. env[["list"]] <- base::list
  4. eval(str2lang(paste0("list(", s, ")")), env)
  5. #> $x
  6. #> [1] 1
英文:
  1. s = &quot;x = 1&quot;
  2. env &lt;- new.env(parent = emptyenv())
  3. env[[&quot;list&quot;]] &lt;- base::list
  4. eval(str2lang(paste0(&quot;list(&quot;, s, &quot;)&quot;)), env)
  5. #&gt; $x
  6. #&gt; [1] 1

The empty env environment is in order to prevent running code other than "list".

huangapple
  • 本文由 发表于 2023年2月10日 07:11:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75405417.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定