as.glht:无法将“列表”类的对象转换为“ glht”对象

时间:2019-01-23 06:15:18

标签: r

我有以下R代码:

# load data
df = read.csv("https://gist.githubusercontent.com/ZeningQu/fa4dbe5a1e82b71f7ebf6e35ec56b72b/raw/3072410fb0ea900fae4dff9cb68c5a2e2a2bab2f/bookflights.csv")
View(df)
df$Subject = factor(df$Subject) # convert to nominal factor
df$International = factor(df$International) # convert to nominal factor
df$Ease = ordered(df$Ease) # convert to ordinal factor

# analyze Ease Likert ratings on Website * International with ordinal logistic regression
library(MASS) # for polr
library(car) # for Anova
# set sum-to-zero contrasts for the Anova call
contrasts(df$Website) <- "contr.sum"
contrasts(df$International) <- "contr.sum"
m = polr(Ease ~ Website * International, data=df, Hess=TRUE) # ordinal logistic
Anova(m, type=3) 

# post hoc pairwise comparisons 
library(multcomp)
library(lsmeans) # equivalent way using lsmeans, pairs, and as.glht
summary(as.glht(pairs(lsmeans(m, pairwise ~ Website * International))),
        test=adjusted(type="none"))

错误:

Error in as.glht.default(pairs(lsmeans(m, pairwise ~ Website * International))) : 
  Cannot convert an object of class ‘list’ to a ‘glht’ object

我知道这是as.glht引发的错误:https://github.com/cran/emmeans/blob/master/R/glht-support.R#L169 但是如何将pairs转换为glht

2 个答案:

答案 0 :(得分:2)

as.glht需要一个类emmGrid or emm_list的对象,因此让我们检查数据:

> class(pairs(lsmeans(m, pairwise ~ Website * International)))
[1] "list"

它不是正确的类,所以让我们尝试将其转换

> class(lsmeans:::as.emm_list(pairs(lsmeans(m, pairwise ~ Website * International))))
[1] "emm_list" "list" 

它似乎已经起作用,因此将其重新插入:

> summary(as.glht(lsmeans:::as.emm_list(pairs(lsmeans(m, pairwise ~ Website * International)))),
+         test=adjusted(type="none"))

     Simultaneous Tests for General Linear Hypotheses

Linear Hypotheses:
                               Estimate Std. Error z value Pr(>|z|)    
Expedia,0 - Orbitz,0 == 0       -2.1442     0.2619  -8.189 2.22e-16 ***
Expedia,0 - Priceline,0 == 0    -0.9351     0.2537  -3.686 0.000228 ***
Expedia,0 - Expedia,1 == 0      -1.6477     0.2570  -6.411 1.44e-10 ***
Expedia,0 - Orbitz,1 == 0       -0.3217     0.2490  -1.292 0.196380    
Expedia,0 - Priceline,1 == 0    -0.7563     0.2517  -3.004 0.002663 ** 
Orbitz,0 - Priceline,0 == 0      1.2091     0.2555   4.732 2.22e-06 ***
Orbitz,0 - Expedia,1 == 0        0.4965     0.2505   1.982 0.047498 *  
Orbitz,0 - Orbitz,1 == 0         1.8225     0.2571   7.089 1.35e-12 ***
Orbitz,0 - Priceline,1 == 0      1.3879     0.2546   5.452 4.99e-08 ***
Priceline,0 - Expedia,1 == 0    -0.7126     0.2518  -2.830 0.004659 ** 
Priceline,0 - Orbitz,1 == 0      0.6134     0.2497   2.457 0.014023 *  
Priceline,0 - Priceline,1 == 0   0.1789     0.2501   0.715 0.474476    
Expedia,1 - Orbitz,1 == 0        1.3260     0.2524   5.254 1.49e-07 ***
Expedia,1 - Priceline,1 == 0     0.8914     0.2506   3.557 0.000375 ***
Orbitz,1 - Priceline,1 == 0     -0.4345     0.2477  -1.754 0.079408 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Adjusted p values reported -- none method)

答案 1 :(得分:2)

重要的是要理解为什么会这样。通话:

lsmeans(m, pairwise ~ Website * International)

实际上是两步操作的简写:

lsm <- lsmeans(m, ~ Website * International)
prs <- pairs(lsm)

结果是两个emmGrid对象lsmprs的列表。

您编写的代码是as.glht(pairs(lsmeans(m, pairwise ~ Website * International))),而内部的pairs(lsmeans(m, pairwise ~ Website * International))已经过大了,因为它会生成结果的每个元素的成对比较。因此,您将获得一个列表,其中包括LS均值的成对比较(可能是您想要的)和成对比较的成对比较(可能不是您想要的)。

这里有两种获取所需结果的方法。一种是省略l.h.s.的公式...

as.glht(pairs(lsmeans(m, ~ Website * International)))

另一种方法是省略pairs()并要求输入您想要的结果的一部分...

as.glht(lsmeans(m, pairwise ~ Website * International)[[2]])

作为 lsmeans / emmeans 的开发人员,我最大的遗憾之一就是两面的公式界面简陋。这就造成了很多混乱和许多类似的问题。但我注定要保持可用状态,因为人们急于一步一步地获得他们想要的所有结果,而不是两步。便利的价格相当高。