如何用两项替换 R 公式中的一项?
How can I replace one term in an R formula with two?
我有一些类似
的东西
y ~ x + z
我想将其转换为
y ~ x_part1 + x_part2 + z
更一般地说,我想要一个函数,它接受一个公式和 returns 该公式,其中所有匹配“^x$”的术语都被 "x_part1" 和 "x_part2" 替换.这是我目前的解决方案,但感觉太笨拙了...
my.formula <- fruit ~ apple + banana
var.to.replace <- 'apple'
my.terms <- labels(terms(my.formula))
new.terms <- paste0('(',
paste0(var.to.replace,
c('_part1', '_part2'),
collapse = '+'),
')')
new.formula <- reformulate(termlabels = gsub(pattern = var.to.replace,
replacement = new.terms,
x = my.terms),
response = my.formula[[2]])
另外一个注意事项是输入公式可能会指定交互。
y ~ b*x + z
应该输出这些(等效)公式之一
y ~ b*(x_part1 + x_part2) + z
y ~ b + (x_part1 + x_part2) + b:(x_part1 + x_part2) + z
y ~ b + x_part1 + x_part2 + b:x_part1 + b:x_part2 + z
MrFlick 提倡使用
替换(y ~ b*x + z, 列表(x=引用(x_part1 + x_part2)))
但是当我将要修改的公式存储在变量中时,如
my.formula <- fruit ~ x + banana
这种方法似乎需要更多的按摩:
substitute(my.formula, list(x=quote(apple_part1 + apple_part2)))
# my.formula
对该方法的必要更改是:
do.call(what = 'substitute',
args = list(apple, list(x=quote(x_part1 + x_part2))))
但是当 'x' 和 c('x_part', 'x_part2') 都存储在具有名称的变量中时,我不知道如何使用这种方法,例如var.to.replace
和 new.terms
以上。
如果只想修改主效应,可以减去x,然后加上两个新变量。
> f <- y ~ x + z
> update(f, .~.-x+x_part1 + x_part2)
y ~ z + x_part1 + x_part2
可以写一个递归函数来修改公式的表达式树:
replace_term <- function(f, old, new){
n <- length(f)
if(n > 1) {
for(i in 1:n) f[[i]] <- Recall(f[[i]], old, new)
return(f)
}
if(f == old) new else f
}
您可以使用它来修改例如交互:
> replace_term(y~x*a+z - x, quote(x), quote(x1 + x2))
y ~ (x1 + x2) * a + z - (x1 + x2)
您可以为此使用substitute
函数
substitute(y ~ b*x + z, list(x=quote(x_part1 + x_part2)))
# y ~ b * (x_part1 + x_part2) + z
这里我们使用命名列表告诉R用表达式x_part1 + x_part2
替换变量x
将公式作为字符串处理怎么样?许多基础 R 模型,如 lm()
接受字符串公式(否则您始终可以使用 formula()
)。在这种情况下,您可以使用 gsub()
:
f1 <- "y ~ x + z"
f2 <- "y ~ b*x + z"
gsub("x", "(x_part1 + x_part2)", f1)
#> [1] "y ~ (x_part1 + x_part2) + z"
gsub("x", "(x_part1 + x_part2)", f2)
#> [1] "y ~ b*(x_part1 + x_part2) + z"
例如,对于mtcars
数据集,假设我们要将mpg
(x)替换为disp + hp
(x_part1 + x_part2) :
f1 <- "qsec ~ mpg + cyl"
f2 <- "qsec ~ wt*mpg + cyl"
f1 <- gsub("mpg", "(disp + hp)", f1)
f2 <- gsub("mpg", "(disp + hp)", f2)
lm(f1, data = mtcars)
#>
#> Call:
#> lm(formula = f1, data = mtcars)
#>
#> Coefficients:
#> (Intercept) disp hp cyl
#> 22.04376 0.01017 -0.02074 -0.56571
lm(f2, data = mtcars)
#>
#> Call:
#> lm(formula = f2, data = mtcars)
#>
#> Coefficients:
#> (Intercept) wt disp hp cyl
#> 20.421318 1.554904 0.026837 -0.056141 -0.876182
#> wt:disp wt:hp
#> -0.006895 0.011126
根据rcorty
的要求,将'x'和c('x_part','x_part2')分别存储在var.to.replace
和new.terms
中,并采纳 MrFlick
的建议使用 setNames
,我们或许可以执行以下操作:
my.formula <- fruit ~ x + banana
var.to.replace <- "x"
new.terms <- c('x_part', 'x_part2')
new.terms1 <- paste(new.terms, collapse="+")
do.call("substitute", list(my.formula, setNames(list(str2lang(new.terms1)), var.to.replace)))
> fruit ~ x_part + x_part2 + banana
顺便说一句,我发现 Paul Johnson 的 Rchaeology(第 2.1 节)具有相关性、教育性和娱乐性。
我有一些类似
的东西y ~ x + z
我想将其转换为
y ~ x_part1 + x_part2 + z
更一般地说,我想要一个函数,它接受一个公式和 returns 该公式,其中所有匹配“^x$”的术语都被 "x_part1" 和 "x_part2" 替换.这是我目前的解决方案,但感觉太笨拙了...
my.formula <- fruit ~ apple + banana
var.to.replace <- 'apple'
my.terms <- labels(terms(my.formula))
new.terms <- paste0('(',
paste0(var.to.replace,
c('_part1', '_part2'),
collapse = '+'),
')')
new.formula <- reformulate(termlabels = gsub(pattern = var.to.replace,
replacement = new.terms,
x = my.terms),
response = my.formula[[2]])
另外一个注意事项是输入公式可能会指定交互。
y ~ b*x + z
应该输出这些(等效)公式之一
y ~ b*(x_part1 + x_part2) + z
y ~ b + (x_part1 + x_part2) + b:(x_part1 + x_part2) + z
y ~ b + x_part1 + x_part2 + b:x_part1 + b:x_part2 + z
MrFlick 提倡使用
替换(y ~ b*x + z, 列表(x=引用(x_part1 + x_part2)))
但是当我将要修改的公式存储在变量中时,如
my.formula <- fruit ~ x + banana
这种方法似乎需要更多的按摩:
substitute(my.formula, list(x=quote(apple_part1 + apple_part2)))
# my.formula
对该方法的必要更改是:
do.call(what = 'substitute',
args = list(apple, list(x=quote(x_part1 + x_part2))))
但是当 'x' 和 c('x_part', 'x_part2') 都存储在具有名称的变量中时,我不知道如何使用这种方法,例如var.to.replace
和 new.terms
以上。
如果只想修改主效应,可以减去x,然后加上两个新变量。
> f <- y ~ x + z
> update(f, .~.-x+x_part1 + x_part2)
y ~ z + x_part1 + x_part2
可以写一个递归函数来修改公式的表达式树:
replace_term <- function(f, old, new){
n <- length(f)
if(n > 1) {
for(i in 1:n) f[[i]] <- Recall(f[[i]], old, new)
return(f)
}
if(f == old) new else f
}
您可以使用它来修改例如交互:
> replace_term(y~x*a+z - x, quote(x), quote(x1 + x2))
y ~ (x1 + x2) * a + z - (x1 + x2)
您可以为此使用substitute
函数
substitute(y ~ b*x + z, list(x=quote(x_part1 + x_part2)))
# y ~ b * (x_part1 + x_part2) + z
这里我们使用命名列表告诉R用表达式x_part1 + x_part2
x
将公式作为字符串处理怎么样?许多基础 R 模型,如 lm()
接受字符串公式(否则您始终可以使用 formula()
)。在这种情况下,您可以使用 gsub()
:
f1 <- "y ~ x + z"
f2 <- "y ~ b*x + z"
gsub("x", "(x_part1 + x_part2)", f1)
#> [1] "y ~ (x_part1 + x_part2) + z"
gsub("x", "(x_part1 + x_part2)", f2)
#> [1] "y ~ b*(x_part1 + x_part2) + z"
例如,对于mtcars
数据集,假设我们要将mpg
(x)替换为disp + hp
(x_part1 + x_part2) :
f1 <- "qsec ~ mpg + cyl"
f2 <- "qsec ~ wt*mpg + cyl"
f1 <- gsub("mpg", "(disp + hp)", f1)
f2 <- gsub("mpg", "(disp + hp)", f2)
lm(f1, data = mtcars)
#>
#> Call:
#> lm(formula = f1, data = mtcars)
#>
#> Coefficients:
#> (Intercept) disp hp cyl
#> 22.04376 0.01017 -0.02074 -0.56571
lm(f2, data = mtcars)
#>
#> Call:
#> lm(formula = f2, data = mtcars)
#>
#> Coefficients:
#> (Intercept) wt disp hp cyl
#> 20.421318 1.554904 0.026837 -0.056141 -0.876182
#> wt:disp wt:hp
#> -0.006895 0.011126
根据rcorty
的要求,将'x'和c('x_part','x_part2')分别存储在var.to.replace
和new.terms
中,并采纳 MrFlick
的建议使用 setNames
,我们或许可以执行以下操作:
my.formula <- fruit ~ x + banana
var.to.replace <- "x"
new.terms <- c('x_part', 'x_part2')
new.terms1 <- paste(new.terms, collapse="+")
do.call("substitute", list(my.formula, setNames(list(str2lang(new.terms1)), var.to.replace)))
> fruit ~ x_part + x_part2 + banana
顺便说一句,我发现 Paul Johnson 的 Rchaeology(第 2.1 节)具有相关性、教育性和娱乐性。