使用R来解释外部使用的符号公式

Jon*_*aus 6 parsing r formula

在R中,公式对象是符号的,似乎很难解析.但是,我需要将这样的公式解析为一组明确的标签,以便在R之外使用.

(1)

让我们来f表示未指定响应的模型公式,例如~V1 + V2 + V3,我尝试过的一件事是:

t <- terms(f)
attr(t, "term.labels")
Run Code Online (Sandbox Code Playgroud)

但是,如果某些变量f属于分类,则不能得到完全明确的含义.例如,V1设为具有2个类别的分类变量,即布尔值,并V2设为double.

因此,指定的模型~V1:V2应具有2个参数:"intercept"和"xyes:z".同时,指定的模型~V1:V2 - 1应具有参数"xno:z"和"xyes:z".但是,没有办法告诉函数terms()哪些变量是分类的(以及有多少类别)无法解释这些变量.相反,它只是V1:V2在其"terms.labels"中,它并不意味着在上下文中V1是绝对的.

(2)

另一方面,使用model.matrix是一种简单的方法来获得我想要的.问题是它需要一个data参数,这对我不好,因为我只想要在R之外使用符号公式的明确解释.这种方法会浪费很多时间(相对而言),因为R必须阅读来自外部来源的数据,当它真正需要知道公式时,哪些变量是分类的(以及多少类别)和哪些变量是双精度的.

有没有办法使用'model.matrix'只指定数据类型而不是实际数据?如果没有,还有什么是可行的解决方案?

Bri*_*ggs 4

嗯,只有在有数据的情况下才能确定给定变量是因子还是数字。所以如果没有 data 参数你就无法做到这一点。但您需要的只是结构,而不是数据本身,因此您可以使用包含所有正确类型的列的 0 行数据框。

f <- ~ V1:V2
V1numeric <- data.frame(V1=numeric(0), V2=numeric(0))
V1factor <- data.frame(V1=factor(c(), levels=c("no","yes")), V2=numeric(0))
Run Code Online (Sandbox Code Playgroud)

查看两个 data.frames:

> V1numeric
[1] V1 V2
<0 rows> (or 0-length row.names)
> str(V1numeric)
'data.frame':   0 obs. of  2 variables:
 $ V1: num 
 $ V2: num 
> V1factor
[1] V1 V2
<0 rows> (or 0-length row.names)
> str(V1factor)
'data.frame':   0 obs. of  2 variables:
 $ V1: Factor w/ 2 levels "no","yes": 
 $ V2: num 
Run Code Online (Sandbox Code Playgroud)

model.matrix与这些一起使用

> model.matrix(f, data=V1numeric)
     (Intercept) V1:V2
attr(,"assign")
[1] 0 1
> model.matrix(f, data=V1factor)
     (Intercept) V1no:V2 V1yes:V2
attr(,"assign")
[1] 0 1 1
attr(,"contrasts")
attr(,"contrasts")$V1
[1] "contr.treatment"
Run Code Online (Sandbox Code Playgroud)

如果你有一个真实的数据集,很容易从中获得一个保留列信息的 0 行 data.frame。只需用 下标即可FALSE。如果您拥有具有正确属性的 data.frame,则无需手动构建 data.frame。

> str(mtcars)
'data.frame':   32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
> str(mtcars[FALSE,])
'data.frame':   0 obs. of  11 variables:
 $ mpg : num 
 $ cyl : num 
 $ disp: num 
 $ hp  : num 
 $ drat: num 
 $ wt  : num 
 $ qsec: num 
 $ vs  : num 
 $ am  : num 
 $ gear: num 
 $ carb: num 
Run Code Online (Sandbox Code Playgroud)