给定一个算术表达式,例如x + y*z,我想将其转换为add(x, multiply(y, z)).

我找到了一个helpful function here:

> getAST <- function(ee) purrr::map_if(as.list(ee), is.call, getAST)
> getAST(quote(x + y*z)) 
[[1]]
`+`

[[2]]
x

[[3]]
[[3]][[1]]
`*`

[[3]][[2]]
y

[[3]][[3]]
z

你可以用rapply(result, as.character, how = "list")来代替符号来获得字符.

如何从这个AST(成绩)中得到add(x, multiply(y, z))分?当有一些括号时,这就变得更复杂了:

> getAST(quote((x + y) * z)) 
[[1]]
`*`

[[2]]
[[2]][[1]]
`(`

[[2]][[2]]
[[2]][[2]][[1]]
`+`

[[2]][[2]][[2]]
x

[[2]][[2]][[3]]
y



[[3]]
z

我不要求答案一定要用getAST的函数.这只是一种可能的方式.

当然,在我的实际用例中,表达式更长.


以下是(我认为)没有括号的情况下的解决方案:

getAST <- function(ee) purrr::map_if(as.list(ee), is.call, getAST)

ast <- rapply(getAST(quote(x + y*z)), as.character, how = "list")

convertAST <- function(ast) {
  op <- switch(
    ast[[1]],
    "+" = "add",
    "-" = "subtract",
    "*" = "multiply",
    "/" = "divide"
  )
  left <- ast[[2]]
  right <- ast[[3]]
  if(is.character(left) && is.character(right)) {
    return(sprintf("%s(%s, %s)", op, left, right))
  }
  if(is.character(left)) {
    return(sprintf("%s(%s, %s)", op, left, convertAST(right)))
  }
  if(is.character(right)) {
    return(sprintf("%s(%s, %s)", op, convertAST(left), right))
  }
  return(sprintf("%s(%s, %s)", op, convertAST(left), convertAST(right)))
}

convertAST(ast)

推荐答案

我们可以像这样使用替换:

subst <- function(e, sub = list(`+` = "add", 
                                `-` = "minus",
                                `/` = "divide",
                                `*` = "multiply")) {
  sub <- Map(as.name, sub)
  do.call("substitute", list(e, sub))
}

# test
e <- quote(x + (y + 1) * z)
res <- subst(e); res
## add(x, multiply((add(y, 1)), z))

# evaluate test against values
add <- `+`; multiply <- `*`; x <- 1; y <- 2; z <- 3
eval(res)
## [1] 10

如果您想要字符串结果,那么

deparse1(subst(e))
## [1] "add(x, multiply((add(y, 1)), z))"

R相关问答推荐

是否可以 Select 安装不带文档的R包以更有效地存储?

在ggplot Likert条中添加水平线

R创建一个数据透视表,计算多个组的百分比

找出疾病消失的受试者

如何在xyplot中 for each 面板打印R^2

使用gcuminc,如何使用逗号格式化风险表?

将非重复序列高效转换为长格式

找出二叉树中每个 node 在R中的深度?

在R中按行按列范围查找最大值的名称

根据类别合并(汇总)某些行

有没有办法使用ggText,<;Sub>;&;<;sup>;将上标和下标添加到同一元素?

安全地测试文件是否通过R打开

计算Mean by分组和绑定到R中的数据集

在ggploy中创建GeV分布时出错

使用函数从R中的列中删除标高

如果极点中存在部分匹配,则替换整个字符串

将仪表板中的值框大小更改为Quarto

如何创建直方图与对齐的每月箱?

我有2011-2022年的年度数据.如何计算最低年份和最高年份之间的差额?

如何在类应用函数中访问函数本身