如何从模型公式中提取变量名称和值?

时间:2016-07-03 15:16:33

标签: r

我想要一个带有n个对象的公式,我需要在函数中使用它。为此,我需要访问该公式的对象,例如,

e <- new.env()
e$y <- matrix(rnorm(20), ncol = 4)
e$x1 <- 2*matrix(rnorm(20), ncol = 4)
e$x2 <- 2*matrix(rnorm(20), ncol = 4)
e$x3 <- 2*matrix(rnorm(20), ncol = 4)

f = formula(y~x1+x2+x3, env = e)
test <- function(formula){
  #A any function using the variables y, x1, x2 and x3
}

1 个答案:

答案 0 :(得分:2)

将您的公式放在合适的环境中

目前,您的公式f仍处于全球环境中:

f <- formula(y~x1+x2+x3, env = e)
environment(f)
# <environment: R_GlobalEnv>

此处env参数无效,因为y~x1+x2+x3很容易成为公式。如果您阅读?formula

 env: the environment to associate with the result, if not already
      a formula.

因此,您需要再采取一步措施将f的环境更改为正确的环境:

environment(f) <- e

或者,为什么不使用as.formula呢?

f <- as.formula("y~x1+x2+x3",env=e)
# y ~ x1 + x2 + x3
# <environment: 0xa1bb67c>

方法1:使用model.frame.default()

z <- model.frame.default(f)

str(z)
# 'data.frame': 5 obs. of  4 variables:
#  $ y : num [1:5, 1:4] 0.601 -1.295 -0.312 0.247 -1.545 ...
#  $ x1: num [1:5, 1:4] 1.801 2.177 -1.68 -0.769 -2.371 ...
#  $ x2: num [1:5, 1:4] -2.407 -0.719 2.588 0.431 -0.787 ...
#  $ x3: num [1:5, 1:4] -3.677 -0.638 -1.325 -2.901 -1.013 ...
#   - attr(*, "terms")=Classes 'terms', 'formula'  language y ~ x1 + x2 + x3
#   .. ..- attr(*, "variables")= language list(y, x1, x2, x3)
#   .. ..- attr(*, "factors")= int [1:4, 1:3] 0 1 0 0 0 0 1 0 0 0 ...
#   .. .. ..- attr(*, "dimnames")=List of 2
#   .. .. .. ..$ : chr [1:4] "y" "x1" "x2" "x3"
#   .. .. .. ..$ : chr [1:3] "x1" "x2" "x3"
#   .. ..- attr(*, "term.labels")= chr [1:3] "x1" "x2" "x3"
#   .. ..- attr(*, "order")= int [1:3] 1 1 1
#   .. ..- attr(*, "intercept")= int 1
#   .. ..- attr(*, "response")= int 1
#   .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 
#   .. ..- attr(*, "predvars")= language list(y, x1, x2, x3)
#   .. ..- attr(*, "dataClasses")= Named chr [1:4] "nmatrix.4" "nmatrix.4" "nmatrix.4" "nmatrix.4"
#   .. .. ..- attr(*, "names")= chr [1:4] "y" "x1" "x2" "x3"

您会获得一个模型框架(具有“术语”属性的数据框;有关详情,请参阅?model.frame?terms.object),您可以将其用作数据框。

方法2:使用terms.formulaall.vars

您也可以使用all.varsget的组合。例如:

list_call <- attr(terms.formula(f), "variables")
# list(y, x1, x2, x3)
z <- setNames(eval(list_call, envir = environment(f)), all.vars(f))

str(z)
# List of 4
#  $ y : num [1:5, 1:4] -0.107 -0.32 0.452 -0.427 0.184 ...
#  $ x1: num [1:5, 1:4] -2.254 0.674 3.754 -1.2 0.734 ...
#  $ x2: num [1:5, 1:4] 0.15 1.28 0.15 4.26 2.74 ...
#  $ x3: num [1:5, 1:4] -1.505 -0.25 -0.462 3.136 1.282 ...

这会给你一个清单。

方法3:get_all_vars() (警告:谨慎使用!)

原则上,这应该是最适合您的解决方案,但不是。

z <- get_all_vars(f)

str(z)
# 'data.frame': 5 obs. of  16 variables:
#  $ y : num  -0.107 -0.32 0.452 -0.427 0.184
#  $ x1: num  -0.762 0.779 -1.139 0.506 -0.483
#  $ x2: num  0.9873 0.2398 0.5705 0.1761 0.0348
#  $ x3: num  0.287 0.625 0.235 -1.243 -0.146
#  $ NA: num  -2.254 0.674 3.754 -1.2 0.734
#  $ NA: num  0.258 -0.242 -2.28 0.375 6.105
#  $ NA: num  1.483 0.345 0.547 -1.084 -0.813
#  $ NA: num  -2.523 -0.642 -0.403 0.706 1.26
#  $ NA: num  0.15 1.28 0.15 4.26 2.74
#  $ NA: num  0.868 -0.572 0.751 -0.731 -1.912
#  $ NA: num  -0.0673 -0.275 1.0924 1.8836 0.633
#  $ NA: num  0.074 -2.958 -1.564 -1.418 2.05
#  $ NA: num  -1.505 -0.25 -0.462 3.136 1.282
#  $ NA: num  -1.45 1.96 1.27 1.21 -1.04
#  $ NA: num  -0.869 2.991 1.268 -1.601 -0.581
#  $ NA: num  -3.286 0.753 -2.75 3.347 -2.161

这为您提供了一个数据框。但是,您应该注意到,最终得到的数据框有16个变量而不是4个。当当公式中的任何变量为矩阵时,get_all_vars()将无法正常工作 。但是,当没有矩阵变量时,这种方法应该是最方便的,所以你也可以记住这个选项。