2013-08-02 39 views
12

我有一个公式,其中包含一些条款和一个数据框(以前的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 

,但我还没有得到一个解决方案放在一起,并且好像我要下去一个兔子洞。想法?

+0

似乎是造成你的问题的主要变量是'log(1 + Days)'。你必须这么称呼吗?或者你可以用一个不同的名字吗? – Thomas

+1

attr(terms.formula(ff),“term.labels”)'? –

+1

我试图想出一个通用的解决方案。因此,任何可能出现在模型中的东西。必须处理由法定公式生成的frame()'。这是问题的一部分。 –

回答

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 

和道具罗马Luštrik指着我在正确的方向。

编辑:看起来你可以把它出掉了 “变量” 属性,以及:

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之类的公式中使用,则会变得非常混乱。

+0

谢谢。再过几分钟我无法接受。在我的情况下,'gsub(...)'不是必需的,我认为 - 空白不匹配不会在那里。我在设置示例时意外地介绍了它。 –

+0

@BenBolker是的,它可能是很好的测试一些其他公式的结构,以查看它是否一般... – Thomas

+1

但你的原始答案,rownames(attr(terms.formula(ff),“factors”))) ',似乎在你的问题案例中工作得很好。 –

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)))]