13

我有一个公式,其中包含一些术语和一个数据框(早期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

但我还没有一个解决方案,而且我好像要掉进兔子洞了。想法?

4

2 回答 2

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

并感谢 Roman Luštrik 为我指明了正确的方向。

编辑:看起来你也可以把它从“变量”属性中拉出来:

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

编辑 2:发现第一个问题案例,涉及I()or offset()

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

不过,使用正则表达式很容易纠正这些问题。但是,如果您遇到诸如调用变量的问题,例如,log(x)并在公式中与诸如I(log(y))for variable之类的东西一起使用y,这将变得非常混乱。

于 2013-08-02T13:21:57.823 回答
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)))]
于 2016-08-09T16:05:29.943 回答