其他人的功能似乎都采用了公式对象,然后在内心深处对他们进行黑暗魔法,我很嫉妒。
我正在编写一个适合多个模型的函数。这些模型的公式部分保持不变,从一个模型到下一个模型的部分变化。笨拙的方法是让用户输入公式部分作为字符串,对它们进行一些字符操作,然后使用as.formula
。
但是在我走这条路之前,我只是想确保我不会忽略一些更干净的方式,它允许函数接受标准R格式的公式(例如从其他公式使用的对象中提取)。
我想要类似......
> LHS <- y~1; RHS <- ~a+b; c(LHS,RHS);
y ~ a + b
> RHS2 <- ~c;
> c(LHS, RHS, RHS2);
y ~ a + b + c
...或
> LHS + RHS;
y ~ a + b
> LHS + RHS + RHS2;
y ~ a + b + c
...但遗憾的是两种语法都不起作用。有人知道是否有什么事情可以做到吗?感谢。
答案 0 :(得分:63)
reformulate
会做你想做的事。
reformulate(termlabels = c('x','z'), response = 'y')
## y ~ x + z
或没有拦截
reformulate(termlabels = c('x','z'), response = 'y', intercept = FALSE)
## y ~ x + z - 1
请注意,您无法构建包含多个reponses
的公式,例如x+y ~z+b
reformulate(termlabels = c('x','y'), response = c('z','b'))
z ~ x + y
从现有formula
中提取条款(根据您的示例)
attr(terms(RHS), 'term.labels')
## [1] "a" "b"
要使响应略有不同,这是一种简单的方法(对于单个变量响应)。
as.character(LHS)[2]
## [1] 'y'
combine_formula <- function(LHS, RHS){
.terms <- lapply(RHS, terms)
new_terms <- unique(unlist(lapply(.terms, attr, which = 'term.labels')))
response <- as.character(LHS)[2]
reformulate(new_terms, response)
}
combine_formula(LHS, list(RHS, RHS2))
## y ~ a + b + c
## <environment: 0x577fb908>
我认为将响应指定为字符向量更为明智,例如
combine_formula2 <- function(response, RHS, intercept = TRUE){
.terms <- lapply(RHS, terms)
new_terms <- unique(unlist(lapply(.terms, attr, which = 'term.labels')))
response <- as.character(LHS)[2]
reformulate(new_terms, response, intercept)
}
combine_formula2('y', list(RHS, RHS2))
您还可以定义一个+
运算符来处理公式(更新为公式对象设置新方法)
`+.formula` <- function(e1,e2){
.terms <- lapply(c(e1,e2), terms)
reformulate(unique(unlist(lapply(.terms, attr, which = 'term.labels'))))
}
RHS + RHS2
## ~a + b + c
您也可以明智地update.formula
使用.
update(~a+b, y ~ .)
## y~a+b