I'm not sure if this is more a programming or statistical (i.e. my lack of understanding) question.
I have a Poisson mixed model that I want to use to compare average counts across groups at different time periods.
mod <- glmer(Y ~ TX_GROUP * time + (1|ID), data = dat, family = poisson)
mod_em <- emmeans(mod, c("TX_GROUP","time"), type = "response")
TX_GROUP time rate SE df asymp.LCL asymp.UCL
0 1 5.743158 0.4566671 Inf 4.914366 6.711723
1 1 5.529303 0.4639790 Inf 4.690766 6.517741
0 2 2.444541 0.2981097 Inf 1.924837 3.104564
1 2 1.467247 0.2307103 Inf 1.078103 1.996855
0 3 4.570218 0.4121428 Inf 3.829795 5.453790
1 3 1.676827 0.2472920 Inf 1.255904 2.238826
Now, I want to estimate the marginal count for the combined time period (2 + 3) for each group. Is it not a simple case of exponentiating the sum of the logged counts from:
contrast(mod_em, list(`2 + 3` = c(0, 0, 1, 0, 1, 0)))
contrast(mod_em, list(`2 + 3` = c(0, 0, 0, 1, 0, 1)))
If I try that the value does not come close to matching the simple mean of the combined groups.
First, I suggest that you put both of your contrasts in one list, e.g.,
contr = list(`2+2|0` = c(0, 0, 1, 0, 1, 0),
`2+3|1` = c(0, 0, 0, 1, 0, 1))
You have to decide when you want to back-transform. See the vignette on transformations and note the discussion on "timing is everything". The two basic options are:
One option: Obtain the marginal means of the log counts, and then back-transform:
mod_con = update(contrast(mod_emm, contr), tran = "log")
summary(mod_con, type = "response")
[The update call is needed because contrast strips off transformations except in special cases, because it doesn't always know what scale to assign to arbitrary linear functions. For example, the difference of two square roots is not on a square-root scale.]
Second option: Back-transform the predictions, then sum them:
mod_emmr = regrid(mod_emm)
contrast(mod_emmr, contr)
The distinction between these results is the same as the distinction between a geometric mean (option 1) and an arithmetic mean (option 2). I doubt that either of them will yield the same results as the raw marginal mean counts, because they are based on the predictions from your model. Personally, I think the first option is the better choice, because sums are a linear operation, and the model is linear on the log scale.
Addendum
There is actually a third option, which is to create a grouping variable. I will illustrate with the pigs dataset.
> pigs.lm <- lm(log(conc) ~ source + factor(percent), data = pigs)
Here are the EMMs for percent:
> emmeans(pigs.lm, "percent")
percent emmean SE df lower.CL upper.CL
9 3.445307 0.04088810 23 3.360723 3.529890
12 3.624861 0.03837600 23 3.545475 3.704248
15 3.662706 0.04372996 23 3.572244 3.753168
18 3.745156 0.05296030 23 3.635599 3.854713
Results are averaged over the levels of: source
Results are given on the log (not the response) scale.
Confidence level used: 0.95
Now let's create a grouping factor group:
> pigs.emm = add_grouping(ref_grid(pigs.lm), "group", "percent", c("1&2","1&2","3&4","3&4"))
> str(pigs.emm)
'emmGrid' object with variables:
source = fish, soy, skim
percent = 9, 12, 15, 18
group = 1&2, 3&4
Nesting structure: percent %in% group
Transformation: “log”
Now get the EMMs for group and note they are just the averages of the respective levels:
> emmeans(pigs.emm, "group")
group emmean SE df lower.CL upper.CL
1&2 3.535084 0.02803816 23 3.477083 3.593085
3&4 3.703931 0.03414907 23 3.633288 3.774574
Results are averaged over the levels of: source, percent
Results are given on the log (not the response) scale.
Confidence level used: 0.95
And here is a summary on the response scale:
> summary(.Last.value, type = "response")
group response SE df lower.CL upper.CL
1&2 34.29790 0.961650 23 32.36517 36.34605
3&4 40.60662 1.386678 23 37.83703 43.57893
Results are averaged over the levels of: source, percent
Confidence level used: 0.95
Intervals are back-transformed from the log scale
These are averages rather than sums, but otherwise it works, and the transformation doesn't get zapped like it does in contrast()
To use the example data from the package, it seems to be fine, though I'd use the grouping in the formula instead.
> warp.lm <- lm(breaks ~ wool*tension, data = warpbreaks)
> warp.emm <- emmeans(warp.lm, c("tension", "wool"))
> warp.emm
tension wool emmean SE df lower.CL upper.CL
L A 44.55556 3.646761 48 37.22325 51.88786
M A 24.00000 3.646761 48 16.66769 31.33231
H A 24.55556 3.646761 48 17.22325 31.88786
L B 28.22222 3.646761 48 20.88992 35.55453
M B 28.77778 3.646761 48 21.44547 36.11008
H B 18.77778 3.646761 48 11.44547 26.11008
Confidence level used: 0.95
Sum of L and M should be 44 + 24 ~ 68 for A and 28 + 28 ~ 56 for B.
> contrast(warp.emm, list(A.LM = c(1, 1, 0, 0, 0, 0),
+ B.LM = c(0, 0, 0, 1, 1, 0)))
contrast estimate SE df t.ratio p.value
A.LM 68.55556 5.157299 48 13.293 <.0001
B.LM 57.00000 5.157299 48 11.052 <.0001
Though I'd use the grouping in the formula.
> warp.em2 <- emmeans(warp.lm, ~tension|wool)
> contrast(warp.em2, list(LM = c(1, 1, 0)))
wool = A:
contrast estimate SE df t.ratio p.value
LM 68.55556 5.157299 48 13.293 <.0001
wool = B:
contrast estimate SE df t.ratio p.value
LM 57.00000 5.157299 48 11.052 <.0001
Thanks. The second method works for me, but not the first (which seems more intuitive) - it doesn't seem to give me back-transformed values:
(mod_em_inj <- emmeans(mod_inj, c("TX_GROUP","time"), type = "response"))
TX_GROUP time rate SE df asymp.LCL asymp.UCL
0 1 5.743158 0.4566671 Inf 4.914366 6.711723
1 1 5.529303 0.4639790 Inf 4.690766 6.517741
0 2 2.444541 0.2981097 Inf 1.924837 3.104564
1 2 1.467247 0.2307103 Inf 1.078103 1.996855
0 3 4.570218 0.4121428 Inf 3.829795 5.453790
1 3 1.676827 0.2472920 Inf 1.255904 2.238826
# Marginal means for combined period (7 - 24 months) - Method 1
(mod_em_inj2 <- emmeans(mod_inj, c("TX_GROUP","time")))
TX_GROUP time emmean SE df asymp.LCL asymp.UCL
0 1 1.7480092 0.07951497 Inf 1.59216273 1.9038557
1 1 1.7100619 0.08391274 Inf 1.54559591 1.8745278
0 2 0.8938574 0.12194916 Inf 0.65484147 1.1328734
1 2 0.3833880 0.15724024 Inf 0.07520279 0.6915732
0 3 1.5195610 0.09018011 Inf 1.34281119 1.6963107
1 3 0.5169035 0.14747615 Inf 0.22785558 0.8059515
contr = list(`2+3|0` = c(0, 0, 1, 0, 1, 0),
`2+3|1` = c(0, 0, 0, 1, 0, 1))
summary(contrast(mod_em_inj2, contr), type = "response")
contrast estimate SE df z.ratio p.value
2+3|0 2.4134184 0.1541715 Inf 15.654 <.0001
2+3|1 0.9002915 0.2198023 Inf 4.096 <.0001
# Marginal means for combined period (7 - 24 months) - Method 2
mod_emmr = regrid(mod_em_inj)
contrast(mod_emmr, contr)
contrast estimate SE df z.ratio p.value
2+3|0 7.014759 0.5169870 Inf 13.569 <.0001
2+3|1 3.144075 0.3448274 Inf 9.118 <.0001
The values of 7.01 and 3.14 are about what I should be getting. Apologies if I'm missing something obvious in your response.
Related
I'm trying to use emmeans to test "contrasts of contrasts" with custom orthogonal contrasts applied to a zero-inflated negative binomial model. The study design has 4 groups (study_group: grp1, grp2, grp3, grp4), each of which is assessed at 3 timepoints (time: Time1, Time2, Time3).
With the code below, I am able to get very close to, but not exactly, what I want. The contrasts that emerge are expressed in terms of ratios such as grp1/grp2, grp1/grp3,..., grp3/grp4 ("lower over higher"; see output following code).
What would be immensely helpful to me to have a way to flip these ratios to be grp2/grp1, grp3/grp1,..., grp4/grp3 ("higher over lower"). I've tried sticking reverse=TRUE in various spots, but to no effect.
Short of re-leveling the study_group factor, is there anyway to do this in emmeans?
Thanks!
library(glmmTMB)
library(emmeans)
set.seed(3456)
# Building grid for study design: 4 groups of 3 sites,
# each with 20 participants observed 3 times
site <- rep(1:12, each=60)
pid <- 1000*site+10*(rep(rep(1:20,each=3),12))
study_group <- c(rep("grp1",180), rep("grp2",180), rep("grp3",180), rep("grp4",180))
grp_num <- c(rep(0,180), rep(1,180), rep(2,180), rep(3,180))
time <- c(rep(c("Time1", "Time2", "Time3"),240))
time_num <- c(rep(c(0:2),240))
# Site-level random effects (intercepts)
site_eff_count = rep(rnorm(12, mean = 0, sd = 0.5), each = 60)
site_eff_zeros = rep(rnorm(12, mean = 0, sd = 0.5), each = 60)
# Simulating a neg binomial outcome
y_count <- rnbinom(n = 720, mu=exp(3.25 + grp_num*0.15 + time_num*-0.20 + grp_num*time_num*0.15 + site_eff_count), size=0.8)
# Simulating some extra zeros
log_odds = (-1.75 + grp_num*0.2 + time_num*-0.40 + grp_num*time_num*0.50 + site_eff_zeros)
prob_1 = plogis(log_odds)
prob_0 = 1 - prob_1
y_zeros <- rbinom(n = 720, size = 1, prob = prob_0)
# Building datasest with ZINB-ish outcome
data_ZINB <- data.frame(site, pid, study_group, time, y_count, y_zeros)
data_ZINB$y_obs <- ifelse(y_zeros==1, y_count, 0)
# Estimating ZINB GLMM in glmmTMB
mod_ZINB <- glmmTMB(y_obs ~ 1
+ study_group + time + study_group*time
+ (1|site),
family=nbinom2,
zi = ~ .,
data=data_ZINB)
#summary(mod_ZINB)
# Getting model-estimated "cell" means for conditional (non-zero) sub-model
# in response (not linear predictor) scale
count_means <- emmeans(mod_ZINB,
pairwise ~ time | study_group,
component="cond",
type="response",
adjust="none")
# count_means
# Defining custom contrast function for orthogonal time contrasts
# contr1 = Time 2 - Time 1
# contr2 = Time 3 - Times 1 and 2
compare_arms.emmc <- function(levels) {
k <- length(levels)
contr1 <- c(-1,1,0)
contr2 <- c(-1,-1,2)
coef <- data.frame()
coef <- as.data.frame(lapply(seq_len(k - 1), function(i) {
if(i==1) contr1 else contr2
}))
names(coef) <- c("T1vT2", "T1T2vT3")
attr(coef, "adjust") = "none"
coef
}
# Estimating pairwise between-group "contrasts of contrasts"
# i.e., testing if time contrasts differ across groups
compare_arms_contrast <- contrast(count_means[[1]],
interaction = c("compare_arms", "pairwise"),
by = NULL)
compare_arms_contrast
applying theemmeans::contrast function as above yields this:
time_compare_arms study_group_pairwise ratio SE df null t.ratio p.value
T1vT2 grp1 / grp2 1.091 0.368 693 1 0.259 0.7957
T1T2vT3 grp1 / grp2 0.623 0.371 693 1 -0.794 0.4276
T1vT2 grp1 / grp3 1.190 0.399 693 1 0.520 0.6034
T1T2vT3 grp1 / grp3 0.384 0.241 693 1 -1.523 0.1283
T1vT2 grp1 / grp4 0.664 0.245 693 1 -1.108 0.2681
.
.
.
T1T2vT3 grp3 / grp4 0.676 0.556 693 1 -0.475 0.6346
Tests are performed on the log scale
The answer, provided by Russ Lenth in the comments and in the emmeans documentation for the contrast function, is to replace pairwise with revpairwise in the contrast function call.
I would like to perform a Cox regression for the following questions: A group of patients receives a treatment "drug" or not (0 / 1). My time variable "time" tells me, how many days the patient is observed and "status" if the patient survived or died (died = 1, survived = 0).
library(survival)
set.seed(123)
df <- data.frame(time = round(runif(100, min = 1, max = 70)),
status = round(runif(100, min = 0, max = 1)),
drug = round(runif(100, min = 0, max = 1)),
age40 = round(runif(100, min = 0, max = 1)),
stringsAsFactors = FALSE)
object <- Surv(df$time, df$status)
model <- coxph(object ~ drug, data = df)
summary(model)
This works fine for me and tells me, that the HR is 0.89, so the drug prevents patients from dying.
Now I want to do some subgroup analysis, f.e. how does the HR change, if the patient is <= 40 years or > 40 years old (age40: 0 vs 1).
Is all I have to do to include the variable "age40" into the coxph?
object2 <- Surv(df$time, df$status)
model2 <- coxph(object2 ~ drug + age40, data = df)
summary(model2)
If I do that my HR in the summary for drug1 slightly changes to 0.86 and I get another one for age40 (1.12).
Now my question is: How are the Hazard Ratios for dying under treatment (drug = 1) if the patient is <= 40 or > 40 years old.
EDIT: Another question would be to graphically show the different HRs of the effect of drug on status in a forest plot, f.e. like this: https://rpkgs.datanovia.com/survminer/reference/ggforest-2.png.
Instead of "sex", "rx", "adhere" etc. I would like to show the HRs for Age40 = 0 vs. 1 and other variables as well, like hypertension = 0 vs. 1, smoker = 0 vs. 1.
Thank you!
The function you need to use is predict on your model2, and it needs to be supplied with a newdata argument that includes all the cases that you want to consider:
exp( predict(model2, newdata=expand.grid(drug=c(0,1), age40=c(0,1))) )
# 1 2 3 4
#1.0000000 0.8564951 1.1268713 0.9651598
You now have all 4 cases of possible combinations of drug and age40. The base case has a value of unity because you are estimating risk ratios form a baseline case of {drug=0, age40=0} You can see what the other risk ratios are associated with
expand.grid(drug=c(0,1), age40=c(0,1))
drug age40
1 0 0
2 1 0
3 0 1
4 1 1
Notice that the ration of drug=0 to drug=1 is the same for each age category considered separately. If you had wanted to see if the effects of drug was different in the two age categories you would have used an interaction model:
model3 <- coxph(object2 ~ drug * age40, data = df)
summary(model3)
#----------------
Call:
coxph(formula = object2 ~ drug * age40, data = df)
n= 100, number of events= 50
coef exp(coef) se(coef) z Pr(>|z|)
drug -0.18524 0.83091 0.45415 -0.408 0.683
age40 0.09611 1.10089 0.39560 0.243 0.808
drug:age40 0.05679 1.05843 0.63094 0.090 0.928
exp(coef) exp(-coef) lower .95 upper .95
drug 0.8309 1.2035 0.3412 2.024
age40 1.1009 0.9084 0.5070 2.390
drug:age40 1.0584 0.9448 0.3073 3.645
Concordance= 0.528 (se = 0.042 )
Likelihood ratio test= 0.34 on 3 df, p=1
Wald test = 0.33 on 3 df, p=1
Score (logrank) test = 0.33 on 3 df, p=1
And the effect estimates are now a bit different:
exp( predict(model3, newdata=expand.grid(drug=c(0,1), age40=c(0,1))) )
# 1 2 3 4
#1.0000000 0.8309089 1.1008850 0.9681861
Use argument strata.
coxph(object ~ drug + strata(age40), data = df)
I'm struggling to calculate an effect size between a continuous predictor's max-min value while using an R lme4 multilevel model.
Simulated data: predictor "x" ranges from 1 to 3
library(tidyverse)
n = 100
a = tibble(y = rep(c("pos", "neg", "neg", "neg"), length.out = n), x = rep(3, length.out = n), group = rep(letters[1:7], length.out = n))
b = tibble(y = rep(c("pos", "pos", "neg", "neg"), length.out = n), x = rep(2, length.out = n), group = rep(letters[1:7], length.out = n))
c = tibble(y = rep(c("pos", "pos", "pos", "neg"), length.out = n), x = rep(1, length.out = n), group = rep(letters[1:7], length.out = n))
d = rbind(a, b)
df = rbind(d, c)
df = df %>% mutate(y = as.factor(y))
df
Model
library("lme4")
m = glmer(
y ~ x + (x | group),
data = df,
family = binomial(link = "logit"))
Output
ggpredict(m, "x")
.
# Predicted probabilities of y
x | Predicted | 95% CI
----------------------------
1 | 0.75 | [0.67, 0.82]
2 | 0.50 | [0.44, 0.56]
3 | 0.25 | [0.18, 0.33]
Adjusted for:
* group = 0 (population-level)
I'm failing to calculate the effect size between the predictor's "x" max (3) and min (1) value
My best try
library("emmeans")
emmeans(m, "x", trans = "logit", type = "response", at = list(x = c(1, 3)))
x response SE df asymp.LCL asymp.UCL
1 0.75 0.0387 Inf 0.667 0.818
3 0.25 0.0387 Inf 0.182 0.333
Confidence level used: 0.95
Intervals are back-transformed from the logit scale
How can I calculate the effect size with CIs between the predictor's "x" max (3) and min (1) value? The effect size should be in probability scale.
I'll try to answer, though I'm still not sure what the question is. I am going to assume that what is wanted is the difference between the two probabilities.
There are a lot of moving parts in the emmeans call shown, so I will proceed in smaller steps. First, let's get estimates of the probabilities in question:
> library(emmeans)
> EMM = emmeans(m, "x", at = list(x = c(1, 3)), type = "response")
> EMM
x prob SE df asymp.LCL asymp.UCL
1 0.75 0.0387 Inf 0.667 0.818
3 0.25 0.0387 Inf 0.182 0.333
Confidence level used: 0.95
Intervals are back-transformed from the logit scale
The quickest way to obtain a pairwise comparison is via
> pairs(EMM)
contrast odds.ratio SE df null z.ratio p.value
1 / 3 9 2.94 Inf 1 6.728 <.0001
Tests are performed on the log odds ratio scale
As stated in the annotations (and also in the documentation, e.g. the vignette on comparisons, when a log or logit transformation is in place, the comparison is shown as a ratio. This happens because the tests are performed on the link (logit) scale, and the difference between logs is the log of a ratio.
If we want the difference between probabilities, it is necessary to create a new object where the primary quantities being estimated are the probabilities, rather than their logits. In emmeans, this may be done via the regrid() function:
> EMMP = regrid(EMM, transform = "response")
> EMMP
x prob SE df asymp.LCL asymp.UCL
1 0.75 0.0387 Inf 0.674 0.826
3 0.25 0.0387 Inf 0.174 0.326
Confidence level used: 0.95
This output looks a lot like the summary of EMM; however, all memory of the logit transformation has been erased, thus the confidence intervals are different because they are calculated directly from the SEs of the prob estimates. For more information, see the vignette on transformations.
So now if we compare these, we get the difference of the probabilities:
> confint(pairs(EMMP))
contrast estimate SE df asymp.LCL asymp.UCL
1 - 3 0.5 0.0612 Inf 0.38 0.62
Confidence level used: 0.95
(Note: I wrapped this in confint() so that we woul;d obtain a confidence interval, rather than the default summary of the t ratio and P value.)
This could be accomplished in one line of code as follows:
confint(pairs(emmeans(m, "x", transform = "response", at = list(x = c(1, 3)))))
The transform argument requests that the reference grid be immediately passed to regrid(). Note that the correct argument here is transform = "response", rather than transform = "logit" (that is, specify what you want to end with, not what you started with). The latter undoes, then redoes, the logit transformation, putting you back where you started.
The emmeans package provides a lot of options, and I really do recommend reading the vignettes.
I have some data about trends over time in drug use across the state. I want to know whether there have been changes in the gender difference in intravenous drug use versus gender differences in all recreational drug use over time.
My data is below. I think I might need to use time-series analysis, but I'm not sure. Any help would be much appreciated.
enter image description here
Since the description in the question does not match the data as there is no information on gender we will assume from the subject that we want to determine if the trends of illicit and iv are the same.
Comparing Trends
Note that there is no autocorrelation in the detrended values of iv or illicit so we will use ordinary linear models.
iv <- c(0.4, 0.3, 0.4, 0.3, 0.2, 0.2)
illicit <- c(5.5, 5.7, 4.8, 4.7, 6.1, 5.3)
time <- 2011:2016
ar(resid(lm(iv ~ time)))
## Call:
## ar(x = resid(lm(iv ~ time)))
##
## Order selected 0 sigma^2 estimated as 0.0024
ar(resid(lm(illicit ~ time)))
## Call:
## ar(x = resid(lm(illicit ~ time)))
##
## Order selected 0 sigma^2 estimated as 0.287
Create a 12x3 data frame long with columns time, value and ind (iv or illicit). Then run a linear model with two slopes and and another with one slope. Both have two intercepts. Then compare them using anova. Evidently they are not significantly different so we cannot reject the hypothesis that the slopes are the same.
wide <- data.frame(iv, illicit)
long <- cbind(time, stack(wide))
fm2 <- lm(values ~ ind/(time + 1) + 0, long)
fm1 <- lm(values ~ ind + time + 0, long)
anova(fm1, fm2)
giving:
Analysis of Variance Table
Model 1: values ~ ind + time + 0
Model 2: values ~ ind/(time + 1) + 0
Res.Df RSS Df Sum of Sq F Pr(>F)
1 9 1.4629
2 8 1.4469 1 0.016071 0.0889 0.7732
Comparing model with slopes to one without slopes
Actually the slopes are not significant in the first place and we cannot reject the hypothesis that both the slopes are zero. Compare to a two intercept model with no slopes.
fm0 <- lm(values ~ ind + 0, long)
anova(fm0, fm2)
giving:
Analysis of Variance Table
Model 1: values ~ ind + 0
Model 2: values ~ ind/(time + 1) + 0
Res.Df RSS Df Sum of Sq F Pr(>F)
1 10 1.4750
2 8 1.4469 2 0.028143 0.0778 0.9258
or running a stepwise regression we find that its favored model is one with two intercepts and no slopes:
step(fm2)
giving:
Start: AIC=-17.39
values ~ ind/(time + 1) + 0
Df Sum of Sq RSS AIC
- ind:time 2 0.028143 1.4750 -21.155
<none> 1.4469 -17.386
Step: AIC=-21.15
values ~ ind - 1
Df Sum of Sq RSS AIC
<none> 1.475 -21.155
- ind 2 172.28 173.750 32.073
Call:
lm(formula = values ~ ind - 1, data = long)
Coefficients:
indiv indillicit
0.30 5.35
log transformed values
If we use log(values) then we similarly find no autocorrelation (not shown) but we do find the slopes of the log transformed values are significantly different.
fm2log <- lm(log(values) ~ ind/(time + 1) + 0, long)
fm1log <- lm(log(values) ~ ind + time + 0, long)
anova(fm1log, fm2log)
giving:
Analysis of Variance Table
Model 1: log(values) ~ ind + time + 0
Model 2: log(values) ~ ind/(time + 1) + 0
Res.Df RSS Df Sum of Sq F Pr(>F)
1 9 0.35898
2 8 0.18275 1 0.17622 7.7141 0.02402 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
I have an analysis i'd like to perform and I have planned out contrasts (not posthoc comparisons!) I would like to make between treatment groups. The treatment group variable has (k =) 4 levels. I plan to make a total of 3 different comparisons, and therefore,—if I understand correctly—I do not need to make any adjustments to the p-values that are calculated since the comparisons are k-1.
I would like to use the multcomp or lsmeans package in R to do this. My question is: Does anyone know if it is possible to do this planned comparison WITHOUT any adjustment made to the confidence intervals (and p-value)? As far as I can tell from the vignettes i've looked at and examples i've seen, the summary.glht() function makes an adjustment as the default and it is not clear to me what option would undo this.
If someone requires a reproducible example, they could use this example that I found on http://www.ats.ucla.edu/stat/r/faq/testing_contrasts.htm:
library(multcomp)
hsb <- read.csv("http://www.ats.ucla.edu/stat/data/hsb2.csv")
m1 <- lm(read ~ socst + factor(ses) * factor(female), data = hsb)
summary(m1)
K <- matrix(c(0, 0, 1, -1, 0, 0, 0), 1)
t <- glht(m1, linfct = K)
summary(t)
As far as I see your example, your question is a little strange. At least IMO, If you needn't adjust, you needn't use multcomp package (but in some situation, it saves us some time).
library(multcomp)
hsb <- read.csv("http://www.ats.ucla.edu/stat/data/hsb2.csv")
hsb$ses <- as.factor(hsb$ses)
m3 <- lm(read ~ socst + ses, data = hsb)
l3 <- glht(m3, linfct = mcp(ses = "Tukey"))
# mcp(~) doesn't run with some type of model. If so, you'll give the matrix directly.
# k3 <- matrix(c(0, 0, 1, 0,
# 0, 0, 0, 1,
# 0, 0, -1, 1), byrow = T, ncol = 4)
# rownames(k3) <- c("2-1", "3-1", "3-2")
# l3 <- glht(m3, linfct = k1)
summary(l3, test=adjusted("none")) # this is the result without adjustment
# Estimate Std. Error t value Pr(>|t|)
# 2 - 1 == 0 0.6531 1.4562 0.448 0.654
# 3 - 1 == 0 2.7034 1.6697 1.619 0.107
# 3 - 2 == 0 2.0503 1.3685 1.498 0.136
hsb$ses <- relevel(hsb$ses, ref="2") # change of the order of levels
m3.2 <- lm(read ~ socst + ses, data = hsb)
summary(m3) # "Without adjustment" means it's equivalent to original model's statistics.
# Estimate Std. Error t value Pr(>|t|)
# :
# ses2 0.65309 1.45624 0.448 0.654
# ses3 2.70342 1.66973 1.619 0.107
summary(m3.2)
# Estimate Std. Error t value Pr(>|t|)
# :
# ses3 2.05033 1.36846 1.498 0.136
# When argument is lmer.obj, summary(~, adjusted("none")) returns p.value by using z value with N(0, 1).