2011-12-09 25 views
4

我想對模型的不同變量運行多重比較分析。我的想法是:如何使用字符作爲函數的屬性

library(multcomp) 
set.seed(123) 
x1 <- gl(4,10) 
x2 <- gl(5,2,40) 
y <- rnorm(40) 

fm1 <- lm(y ~ x1 + x2) 

for(var in c('x1', 'x2')) 
{ 
mc1 <- glht(fm1, linfct=mcp(var='Tukey')) 
print(summary(mc1)) 
} 

當我跑,我得到以下錯誤:

Error en mcp2matrix(model, linfct = linfct) : 
    Variable(s) ‘var’ have been specified in ‘linfct’ but cannot be found in ‘model’! 

That is, it is not possible to use a character to specify an attribute of the mcp function. Anyone knows a solution?

回答

3

更新:確保看到哈德利的答案這樣做,的更好的方式,而不訴諸字符串粘貼我的回答仍然是解釋有用這是爲什麼在這個更難比平常。 )

mcp()的特性要求您使用相對蠻力的方法將表達式粘貼在一起,然後將其傳遞給eval(parse())

棘手的是,mcp()以非標準方式解釋其第一個參數。在mcp()之內,x1 = 'Tukey'不是(正如通常那樣)意思是「爲參數x1賦值'Tukey'」。相反,整個事物被解釋爲對比的象徵性描述。 (在這裏,它很像是更熟悉的公式對象,例如lm()調用中的y ~ x1 + x2)。

for(var in c('x1', 'x2')) { 
    # Construct a character string with the expression you'd type at the command 
    # line. For example : "mcp(x1 = 'Tukey')" 
    exprString <- paste("mcp(", var, "='Tukey')") 
    # eval(parse()) it to get an 'mcp' object. 
    LINFCT <- eval(parse(text = exprString)) 
    mc1 <- glht(fm1, linfct = LINFCT) 
    print(summary(mc1)) 
} 
+0

+1好手法。謝謝喬希。 –

+0

幾乎總是更好地使用替代而不是文字操作。 – hadley

+0

雖然可能會很棘手。另一種選擇是do.call和setNames – hadley

2

Have you tried: eval(parse(text='variable'))assign

13

它通常是更好地避免與代表代碼儘可能串的工作 - 它可以防止那些難以調試的錯誤,和美觀是更優雅。這個問題原來是相當容易,如果你使用do.call解決和setNames功能:

var <- "x1" 
cmp <- do.call(mcp, setNames(list("Tukey"), var)) 
glht(fm1, linfct = cmp) 

不能使用substitute這裏,因爲它不允許你修改的功能參數的名稱。我有一些直覺,爲什麼這是合理的,但還不足以解釋它:/

如果你是一個軟件包的作者,最好提供一個替代版本的函數,使用不尋常的語法,以便他們可以訪問以編程方式而不用跳過籃球。

+2

+1非常推薦@hadley –

+1

+1非常感謝您花時間展示'setNames()'的用法。我很久沒有想到'x1 = Tukey'真的會評估到一個指定的列表。我現在在我自己的開始時添加了一個指向你的答案的指針。 –

+1

do.call的輸入是一個命名列表。 – hadley

相關問題