提取公式括号内的信息

Extract information inside parentheses of formula

我正在编写一个 R 包,用户可以在其中编写如下所示的公式:

outcome ~ var1 + var2 + mm(id, mmc(var3, var4), mmw(pupils^exp(teacher*b)))

右侧包括变量名称和元素 mm(),它本身包含变量名称 (id) 以及元素 mmc() 和 mmw()。

我想分开 mm()、mmc()、mmw(),即以变量结尾

mm  = id, mmc(var3, var4), mmw(pupils^exp(teacher*b))
mmc = var3, var4
mmw = pupils^exp(teacher*b)

我唯一的选择是将公式解析为字符,然后使用正则表达式分隔元素,还是有办法更优雅地处理它,因为它是一个公式?

我试过了

all.vars
all.names

但它们将 mmw() 分解得太多,因为 mmw() 通常包含非线性函数关系

1) 使用中的getTerms我们可以不使用正则表达式直接解析公式。首先我们得到术语 tt 然后形成 mm 这是具有多个元素的术语。从中提取其他的。没有使用包。

fo <- outcome ~ var1 + var2 + mm(id, mmc(var3, var4), mmw(pupils^exp(teacher * b)))

tt <- getTerms(fo[[3]])
mm <- as.list(tt[lengths(tt) > 1][[1]])[-1]
mmc <- as.list(mm[[2]][-1])
mmw <- as.list(mm[[3]][-1])

给予:

> mm
[[1]]
id

[[2]]
mmc(var3, var4)

[[3]]
mmw(pupils^exp(teacher * b))

> mmc
[[1]]
var3

[[2]]
var4

> mmw
[[1]]
pupils^exp(teacher * b)

2) 或者我们可以将处理权合并到 getTerms 中,给出 getMs 如下:

getMs <- function(e, x = list()) {
  if (length(e) == 1) x
  else if (identical(e[[1]], as.name("+")))
    c( Recall(e[[2]], x), Recall(e[[3]], x) )
  else if (as.character(e[[1]]) %in% c("mm", "mmw", "mmc")) {
      for(i in 2:length(e)) x <- Recall(e[[i]], x)
      c(setNames(list(as.list(e[-1])), as.character(e[[1]])), x)
  } else x
}
res <- getMs(fo[[3]])
str(res)

给予:

List of 3
 $ mm :List of 3
  ..$ : symbol id
  ..$ : language mmc(var3, var4)
  ..$ : language mmw(pupils^exp(teacher * b))
 $ mmw:List of 1
  ..$ : language pupils^exp(teacher * b)
 $ mmc:List of 2
  ..$ : symbol var3
  ..$ : symbol var4