【问题标题】:R: evaluate comma-separated string as an expressionR:将逗号分隔的字符串评估为表达式
【发布时间】:2021-08-12 22:59:02
【问题描述】:

我有一个逗号分隔的字符串,我想将它作为逗号分隔的表达式插入到函数中。具体来说,有各种函数将... 作为参数,我希望有一种方法可以将逗号分隔的字符串转换为逗号分隔的参数列表,这些参数可以“注入”到... 中的参数中函数调用。我尝试使用parseeval,正如on this page 所暗示的那样,但我仍然无法让我的功能正常工作。

下面是我正在尝试做的一个可重现的示例。

这很好用

a <- 1
b <- 2
sum(a, b)

如果ab 被编码在一个字符串中,我无法让它们在sum 函数中进行评估

这失败了,因为myString 属于字符类,并且该函数尝试按原样评估它,而不是将其解析为组件ab

myString <- 'a, b'
sum(myString)

尝试使用parseeval 也失败了

这些给出关于意外逗号的错误。

sum(parse(text = myString))
sum(eval(parse(text = mystring)))

输出:

Error in parse(text = myString) : <text>:1:2: unexpected ','
1: a,
     ^

我必须在 myString 上使用什么函数或一组函数 (fxn) 才能正确评估 sum

我想要的解决方案将采用以下格式,其中 fxn 是必须在myString 上使用sum 函数之前的函数:

# Acceptable solution format
sum(fxn(myString))

# Alternatively by piping
myString %>%
    fxn %>%
    sum

更新:

如果myString 中编码的值不止两个,则解决方案必须具有足够的泛化性以处理。例如,如果满足以下条件,解决方案也必须有效:

c <- 3
d <- 4
e <- 5
myString2 <- 'c, d, e'

# This:
sum(fxn(myString2))

# Must yield `12`

此外,结果应该具有足够的泛化性,可以适用于将... 作为参数的各种函数,而不仅仅是sum。为简单起见,我选择了sum 作为示例。然而,下面是另一个期望行为的例子:

f <- 6
g <- 7
myString3 <- 'f, g'

# This:
prod(fxn(myString3))

# Must yield `42`

【问题讨论】:

  • 这会很困难。 sum 是否必须是管道中的一个单独步骤?你可以使用do.call吗?还是purrr::lift
  • 我不熟悉purrr::lift,所以我很想看看它是如何使用的。我可以接受依赖do.call 的解决方案,因为我最近开始学习如何使用它,但我还没有找到一个干净的解决方案(还)。如果您有一个解决方案,其中sum 不是一个单独的步骤,那么我很想看看,:)。 一个重要的限制是,解决方案必须可推广到sum 中的任意数量的参数(例如,如果myString &lt;- 'a, b, c, d'。我将更新问题以反映这一点。
  • 我还要澄清一下,sum 在这个例子中的作用只是为了做一个可重现的例子。任何采用... 的函数都是合适的。我正在寻找将逗号分隔的字符串转换为逗号分隔的表达式的通用策略,该表达式可以“注入”到以... 作为参数的函数中。同样,我将更新问题以反映此约束。
  • 感谢您的澄清,否则sum(eval(parse(text=paste("c(",myString,")")))) 会起作用
  • 您还可以澄清逗号分隔的元素是否始终是单个符号,或者是否需要评估它们(例如myString &lt;- 'log(x), y + z, w

标签: r string parsing expression eval


【解决方案1】:

我认为解决方案是使用strsplit,然后通过sapply()获取()每个值。

a <- 1
b <- 2
c <- 3
d <- 4
myString <- 'a, b, c, d'

fxn <- function(myString) 
{
  values <- unlist(strsplit(myString, split = ", "))
  sapply(values, function(x){get(x)})
}
sum(fxn(myString))

[1] 10

【讨论】:

  • 不错。我尝试了与mget() 类似的方法,但遇到了环境问题。
  • 我认为这个解决方案适用于一般情况。 fxn() 返回值向量。尝试使用我的代码 fxn(...) (无总和)。 'prod(fxn(myString))' = 24,也意味着这是有效的。对不起,如果这仍然不是你的重点。
  • 代码对我来说很好用。请问'myString3'是不是错字?
  • 因为你分配的 g 会干扰本地环境,所以将我的“g”​​编辑为任何独特的东西应该没问题。
  • 谢谢皮特!您对重叠的变量名称很满意。感谢您指出我的疏忽,也感谢您提供强大的解决方案。我现在已经接受了你的回答,:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多