2013-08-02 75 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)))]