提取公式括号内的信息
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
我正在编写一个 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