如何将R公式中的一个项替换为两个?

时间:2016-08-09 15:12:31

标签: r formula

我有一些基本的内容

y ~ x + z

我想将其转换为

y ~ x_part1 + x_part2 + z

更一般地说,我希望有一个函数,它接受一个公式,并返回所有匹配" ^ 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,list(x = quote(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))))

但是当我们同时使用这种方法时,我无法弄清楚如何使用这种方法。和c(&#39; x_part&#39;,&#39; x_part2&#39;)存储在具有名称的变量中,例如上面有var.to.replacenew.terms

4 个答案:

答案 0 :(得分:6)

您可以使用substitute功能

substitute(y ~ b*x + z, list(x=quote(x_part1 + x_part2)))
# y ~ b * (x_part1 + x_part2) + z

这里我们使用命名列表告诉R用表达式x替换变量x_part1 + x_part2

答案 1 :(得分:3)

您可以编写递归函数来修改公式的表达式树:

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)

答案 2 :(得分:1)

如果您只想修改主效果,可以减去x,并添加两个新变量。

> f <- y ~ x + z
> update(f, .~.-x+x_part1 + x_part2)
y ~ z + x_part1 + x_part2

答案 3 :(得分:0)

如何将公式作为字符串使用?许多基础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