我正在编写一个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()分解得太多
那呢?您可以将公式拆分为+
,当您使用sort()
时,它应该始终是同一顺序,因此x
是结果的第一个元素,可以在其中应用一些正则表达式。
f <- outcome ~ var1 + var2 + mm(id, mmc(var3, var4), mmw(pupils^exp(teacher*b)))
x <- sort(el(strsplit(as.character(f)[3], " \\+ ")))[1]
id = gsub("^mm\\((.*)\\)$", "\\1", x)
mmc = gsub(".*mmc\\((.*?)\\).*", "\\1", x)
mmw = gsub(".*mmw\\((.*?\\))\\).*", "\\1", x)
c(id, mmc, mmw)
# [1] "id, mmc(var3, var4), mmw(pupils^exp(teacher * b))"
# [2] "var3, var4"
# [3] "pupils^exp(teacher * b)"
使用getTerms
中的Terms of a sum in a R expression,我们可以直接解析公式。首先我们得到项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)