从数据框中提取公式中的变量

时间:2013-08-02 13:12:25

标签: r formula

我有一个公式,其中包含一些术语和一个数据框(早期model.frame()调用的输出),其中包含所有这些术语等等。我希望模型框架的子集只包含公式中出现的变量。

ff <- log(Reaction) ~ log(1+Days) + x + y
fr <- data.frame(`log(Reaction)`=1:4,
                 `log(1+Days)`=1:4,
                 x=1:4,
                 y=1:4,
                 z=1:4,
                 check.names=FALSE)

所需的结果是fr减去z列(fr[,1:4]作弊 - 我需要一个程序化解决方案......)

的一些策略:

fr[all.vars(ff)]
## Error in `[.data.frame`(fr, all.vars(ff)) : undefined columns selected

(因为all.vars()获得了"Reaction",而不是log("Reaction")

stripwhite <- function(x) gsub("(^ +| +$)","",x)
vars <- stripwhite(unlist(strsplit(as.character(ff)[-1],"\\+")))
fr[vars]
## Error in `[.data.frame`(fr, vars) : undefined columns selected

(因为+上的拆分会虚假地拆分log(1+Days)字词。

我一直在考虑走下公式的解析树:

ff[[3]]       ## log(1 + Days) + x + y
ff[[3]][[1]]  ## `+`
ff[[3]][[2]]  ## log(1 + Days) + x

但是我没有把解决方案放在一起,看起来我正在走下一个兔子洞。想法?

2 个答案:

答案 0 :(得分:4)

这应该有效:

> fr[gsub(" ","",rownames(attr(terms.formula(ff), "factors")))]
  log(Reaction) log(1+Days) x y
1             1           1 1 1
2             2           2 2 2
3             3           3 3 3
4             4           4 4 4

并向罗马·鲁斯特里克道具指示我指向正确的方向。

编辑:看起来你也可以从“变量”属性中删除它:

fr[gsub(" ","",attr(terms(ff),"variables")[-1])]

编辑2:找到第一个问题案例,涉及I()offset()

ff <- I(log(Reaction)) ~ I(log(1+Days)) + x + y
fr[gsub(" ","",attr(terms(ff),"variables")[-1])]

然而,使用正则表达式可以很容易地纠正这些问题。但是,如果您遇到调用变量的问题,例如log(x),并且在公式中使用I(log(y))等变量y,则会变得非常混乱

答案 1 :(得分:0)

在我看来,唯一的问题是fr的第二列名称中缺少空格。用空格重命名并以这种方式拉列:

ff <- log(Reaction) ~ log(1+Days) + x + y
fr <- data.frame(`log(Reaction)`=1:4,
                 `log(1 + Days)`=1:4,
                 x=1:4,
                 y=1:4,
                 z=1:4,
                 check.names=FALSE)


fr[labels(terms(ff))]

如果您认为两者之间的唯一区别始终是fr的名称中包含ff中的名称的空格,那么上述解决方案就成立了。不过,我更喜欢labels(terms(x)),因为它看起来有点抽象。

fr[gsub(pattern = ' ', replacement = '', x = labels(terms(ff)))]