\documentclass[11pt]{article} \usepackage[margin=1in]{geometry} \usepackage{mathpazo} \usepackage{hyperref} \usepackage{fancyvrb} \usepackage{multicol} \usepackage{natbib} \usepackage{Sweave} \hypersetup{colorlinks=true,allcolors=black,urlcolor=blue} \let\dq=" \DefineShortVerb{\"} \def\pkg{\textbf} \def\proglang{\textsf} \def\lsm{\pkg{lsmeans}} % double-quoted text \def\dqt#1{\code{\dq{}#1\dq{}}} % The objects I want to talk about \def\rg{\dqt{ref.grid}} \def\lsmo{\dqt{lsmobj}} % for use in place of \item in a description env where packages are listed \def\pitem#1{\item[\pkg{#1}]} \def\R{\proglang{R}} \def\SAS{\proglang{SAS}} \def\code{\texttt} \def\Fig#1{Figure~\ref{#1}} \def\bottomfraction{.5} %\VignetteIndexEntry{Using lsmeans} %\VignetteDepends{lsmeans} %\VignetteKeywords{least-squares means} %\VignettePackage{lsmeans} % Initialization <>= options(show.signif.stars=FALSE, prompt="R> ", continue=" ", useFancyQuotes=FALSE, width=100, digits=6) @ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% almost as usual \author{Russell V.~Lenth\\The University of Iowa} \title{Using \lsm{}} %% without formatting \ifx %xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx %% for pretty printing and a nice hypersummary also set: \Plainauthor{Russell V.~Lenth} %% comma-separated \Plaintitle{Least-squares Means: The R Package lsmeans} %% without formatting \Shorttitle{The R Package lsmeans} %% a short title (if necessary) \fi %xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ifx % IGNORE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx %% The address of (at least) one author should be given %% in the following format: \Address{ Russell V.~Lenth, Professor Emeritus\\ Department of Statistics and Actuarial Science\\ % 241 Schaeffer Hall\\ The University of Iowa\\ Iowa City, IA 52242 ~ USA\\ E-mail: \email{russell-lenth@uiowa.edu} %\\ % URL: \url{http://www.stat.uiowa.edu/~rlenth/} } %% It is also possible to add a telephone and fax number %% before the e-mail in the following format: %% Telephone: +43/1/31336-5053 %% Fax: +43/1/31336-734 \fi %xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx %% for those who use Sweave please include the following line (with % symbols): %% need no \usepackage{Sweave.sty} %% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \maketitle{} \begin{abstract} Least-squares means are predictions from a linear model, or averages thereof. They are useful in the analysis of experimental data for summarizing the effects of factors, and for testing linear contrasts among predictions. The \lsm{} package provides a simple way of obtaining least-squares means and contrasts thereof. It supports many models fitted by \R{} core packages (as well as a few key contributed ones) that fit linear or mixed models, and provides a simple way of extending it to cover more model classes. \end{abstract} \section{Introduction} Least-squares means (LS~means for short) for a linear model are simply predictions---or averages thereof---over a regular grid of predictor settings which I call the \emph{reference grid}. They date back at least to 1976 when LS~means were incorporated in the contributed \SAS{} procedure named \code{HARVEY} \citep{Har76}. Later, they were incorporated via \code{LSMEANS} statements in the regular \SAS{} releases. In simple analysis-of-covariance models, LS~means are the same as covariate-adjusted means. In unbalanced factorial experiments, LS~means for each factor mimic the main-effects means but are adjusted for imbalance. The latter interpretation is quite similar to the ``unweighted means'' method for unbalanced data, as presented in old design books. LS~means are not always well understood, in part because the term itself is confusing. The most important things to remember are: \begin{itemize} \item LS~means are computed relative to a \emph{reference grid}. \item Once the reference grid is established, LS~means are simply predictions on this grid, or marginal averages of a table of these predictions. \end{itemize} A user who understands these points will know what is being computed, and thus can judge whether or not LS~means are appropriate for the analysis. \section{The reference grid} Since the reference grid is fundamental, it is our starting point. For each predictor in the model, we define a set of one or more \emph{reference levels}. The reference grid is then the set of all combinations of reference levels. If not specified explicitly, the default reference levels are obtained as follows: \begin{itemize} \item For each predictor that is a factor, its reference levels are the unique levels of that factor. \item Each numeric predictor has just one reference level---its mean over the dataset. \end{itemize} So the reference grid depends on both the model and the dataset. \subsection{Example: Orange sales} To illustrate, consider the "oranges" data provided with \lsm{}. This dataset has sales of two varieties of oranges (response variables "sales1" and "sales2") at 6 stores (factor "store"), over a period of 6 days (factor "day"). The prices of the oranges (covariates "price1" and "price2") fluctuate in the different stores and the different days. There is just one observation on each store on each day. For starters, let's consider an additive covariance model for sales of the first variety, with the two factors and both "price1" and "price2" as covariates (since the price of the other variety could also affect sales). <<>>= library("lsmeans") oranges.lm1 <- lm(sales1 ~ price1 + price2 + day + store, data = oranges) anova(oranges.lm1) @ The "ref.grid" function in \lsm{} may be used to establish the reference grid. Here is the default one: <<>>= ( oranges.rg1 <- ref.grid(oranges.lm1) ) @ As outlined above, the two covariates "price1" and "price2" have their means as their sole reference level; and the two factors have their levels as reference levels. The reference grid thus consists of the $1\times1\times6\times6=36$ combinations of these reference levels. LS~means are based on predictions on this reference grid, which we can obtain using "predict" or "summary": <<>>= summary(oranges.rg1) @ \subsection{LS means as marginal averages over the reference grid} The ANOVA indicates there is a significant "day" effect after adjusting for the covariates, so we might want to do a follow-up analysis that involves comparing the days. The "lsmeans" function provides a starting point: <<>>= lsmeans(oranges.rg1, "day") ## or lsmeans(oranges.lm1, "day") @ These results, as indicated in the annotation in the output, are in fact the averages of the predictions shown earlier, for each day, over the 6 stores. The above LS~means are not the same as the overall means for each day: <<>>= with(oranges, tapply(sales1, day, mean)) @ These unadjusted means are not comparable with one another because they are affected by the differing "price1" and "price2" values on each day, whereas the LS~means are comparable because they use predictions at uniform "price1" and "price2" values. Note that one may call "lsmeans" with either the reference grid or the model. If the model is given, then the first thing it does is create the reference grid; so if the reference grid is already available, as in this example, it's more efficient to make use of it. \subsection{Altering the reference grid} The "at" argument may be used to override defaults in the reference grid. The user may specify this argument either in a "ref.grid" call or an "lsmeans" call; and should specify a "list" with named sets of reference levels. Here is a silly example: <<>>= lsmeans(oranges.lm1, "day", at = list(price1 = 50, price2 = c(40,60), day = c("2","3","4")) ) @ Here, we restricted the results to three of the days, and used different prices. One possible surprise is that the predictions are averaged over the two "price2" values. That is because "price2" is no longer a single reference level, and we average over the levels of all factors not used to split-out the LS~means. This is probably not what we want. To get separate sets of predictions for each "price2", one must specify it as another factor or as a "by" factor in the "lsmeans" call (we will save the result for later discussion): <<>>= org.lsm <- lsmeans(oranges.lm1, "day", by = "price2", at = list(price1 = 50, price2 = c(40,60), day = c("2","3","4")) ) org.lsm @ Note: We could have obtained the same results using any of these: <>= lsmeans(oranges.lm1, ~ day | price, at = ... ) # Ex 1 lsmeans(oranges.lm1, c("day","price2"), at = ... ) # Ex 2 lsmeans(oranges.lm1, ~ day * price, at = ... ) # Ex 3 @ Ex~1 illustrates the formula method for specifying factors, which is more compact. The "|" character replaces the "by" specification. Ex~2 and Ex~3 produce the same results, but their results are displayed as one table (with columns for "day" and "price") rather than as two separate tables. \section{Working with the results} \subsection{Objects} The "ref.grid" function produces an object of class \rg{}, and the "lsmeans" function produces an object of class \lsmo{}, which is a subclass of \rg. There is really no practical difference between these two classes except for their "show" methods---what is displayed by default---and the fact that an \lsmo{} is not (necessarily) a true reference grid as defined earlier in this article. Let's use the "str" function to examine the \lsmo{} object just produced: <<>>= str(org.lsm) @ We no longer see the reference levels for all predictors in the model---only the levels of "day" and "price2". These \emph{act} like reference levels, but they do not define the reference grid upon which the predictions are based. \subsection{Summaries} There are several methods for \rg{} (and hence also for \lsmo{}) objects. One already seen is "summary". It has a number of arguments---see its help page. In the following call, we summarize "days.lsm" differently than before. We will also save the object produced by "summary" for further discussion. <<>>= ( org.sum <- summary(org.lsm, infer = c(TRUE,TRUE), level = .90, adjust = "bon", by = "day") ) @ The "infer" argument causes both confidence intervals and tests to be produced; the default confidence level of $.95$ was overridden; a Bonferroni adjustment was applied to both the intervals and the $P$~values; and the tables are organized the opposite way from what we saw before. What kind of object was produced by "summary"? Let's see: <<>>= class(org.sum) @ The \dqt{summary.ref.grid} class is an extension of \dqt{data.frame}. It includes some attributes that, among other things, cause additional messages to appear when the object is displayed. But it can also be used as a \dqt{data.frame} if the user just wants to use the results computationally. For example, suppose we want to convert the LS~means from dollars to Russian rubles (at the July 13, 2014 exchange rate): {\small <<>>= transform(org.sum, lsrubles = lsmean * 34.2) @ } Observe also that the summary is just one data frame with six rows, rather than a collection of three data frames; and it contains a column for all reference variables, including any "by" variables. Besides "str" and "summary", there is also a "confint" method, which is the same as "summary" with "infer=c(TRUE,FALSE)", and a "test" method (same as "summary" with "infer=c(FALSE,TRUE)", by default). The "test" method may in addition be called with "joint=TRUE" to obtain a joint test that all or some of the linear functions are equal to zero or some other value. There is also an "update" method which may be used for changing the object's display settings. For example: <<>>= org.lsm2 <- update(org.lsm, by.vars = NULL, level = .99) org.lsm2 @ \subsection{Plots} Confidence intervals for LS~means may be displayed graphically, using the "plot" method. For example: <>= plot(org.lsm, by = "price2") @ The resulting display is shown in \Fig{org-plot}. This function requires that the \pkg{lattice} package be installed. \begin{figure} \begin{center} \includegraphics{using-lsmeans-org-plot.pdf} \end{center} \caption{Confidence intervals for LS~means in the \code{oranges} example.}\label{org-plot} \end{figure} \section{Contrasts and comparisons} \subsection{Contrasts in general} Often, people want to do pairwise comparisons of LS~means, or compute other contrasts among them. This is the purpose of the "contrast" function, which uses a \dqt{ref.grid} or \dqt{lsmobj} object as input. There are several standard contrast families such as \dqt{pairwise}, \dqt{trt.vs.ctrl}, and \dqt{poly}. In the following command, we request \dqt{eff} contrasts, which are differences between each mean and the overall mean: <<>>= contrast(org.lsm, method = "eff") @ Note that this preserves the "by" specification from before, and obtains the effects for each group. In this example, since it is an additive model, we obtain exactly the same results in each group. This isn't wrong, it's just redundant. Another popular method is Dunnett-style contrasts, where a particular LS~mean is compared with each of the others. This is done using \dqt{trt.vs.ctrl}. In the following, we obtain (again) the LS~means for days, and compare each with the average of the LS~means on day~5 and~6. <<>>= days.lsm <- lsmeans(oranges.rg1, "day") contrast(days.lsm, "trt.vs.ctrl", ref = c(5,6)) @ For convenience, \dqt{trt.vs.ctrl1} and \dqt{trt.vs.ctrlk} methods are provided for use in lieu of "ref" for comparing with the first and the last LS~means. Note that by default, "lsmeans" results are displayed with confidence intervals while "contrast" results are displayed with $t$ tests. One can easily override this; for example, <>= confint(contrast(days.lsm, "trt.vs.ctrlk")) @ (Results not shown.) In the above examples, a default multiplicity adjustment is determined from the contrast method. This may be overridden by adding an "adjust" argument. \subsection{Pairwise comparisons} Often, users want pairwise comparisons among the LS~means. These may be obtained by specifying \dqt{pairwise} or \dqt{revpairwise} as the "method" argument in the call to "contrast". For group labels $A,B,C$, \dqt{pairwise} generates the comparisons $A-B, A-C, B-C$ while \dqt{revpairwise} generates $B-A, C-A, C-B$. As a convenience, a "pairs" method is provided that calls "contrast" with "method="\dqt{pairwise}: <<>>= pairs(org.lsm) @ There is also a "cld" (compact letter display) method that lists the LS~means along with grouping symbols for pairwise contrasts. It requires the \pkg{multcompView} package \citep{mcview} to be installed. <<>>= cld(days.lsm, alpha = .10) @ Two LS~means that share one or more of the same grouping symbols are not significantly different at the stated value of "alpha", after applying the multiplicity adjustment (in this case Tukey's HSD). By default, the LS~means are ordered in this display, but this may be overridden with the argument "sort=FALSE". "cld" returns a \dqt{summary.ref.grid} object, not an "lsmobj". Another way to display pairwise comparisons is via the "comparisons" argument of "plot". When this is set to "TRUE", arrows are added to the plot, with lengths set so that the amount by which they overlap (or don't overlap) matches as closely as possible to the amounts by which corresponding confidence intervals for differences cover (or don't cover) the value zero. This does not always work, and if there are discrepancies, a message is printed. But it usually works. <>= plot(days.lsm, comparisons = TRUE, alpha = .10) @ \Fig{days-cmp} shows the result. Note that the pairs of means having overlapping arrows are the same as those grouped together in the "cld" display. However, these comparison arrows show more about the degree of significance in the comparisons. The lowest and highest LS~mean have arrows pointing only inward, as the others are not needed. If the confidence intervals and arrows together look too cluttered, one can add the argument \code{intervals = FALSE}, then only the arrows will be displayed. \begin{figure} \begin{center} \includegraphics{using-lsmeans-days-cmp.pdf} \end{center} \caption{Graphical comparisons of the LS~means for \code{days}.}\label{days-cmp} \end{figure} \section{Multivariate models} The "oranges" data has two response variables. Let's try a multivariate model for predicting the sales of the two varieties of oranges, and see what we get if we call "ref.grid": <<>>= oranges.mlm <- lm(cbind(sales1,sales2) ~ price1 + price2 + day + store, data = oranges) ref.grid(oranges.mlm) @ What happens is that the multivariate response is treated like an additional factor, by default named "rep.meas". In turn, it can be used to specify levels for LS~means. Here we rename the multivariate response to \dqt{variety} and obtain "day" means (and a compact letter display for comparisons thereof) for each "variety": <<>>= org.mlsm <- lsmeans(oranges.mlm, ~ day | variety, mult.name = "variety") cld(org.mlsm, sort = FALSE) @ \section{Contrasts of contrasts} With the preceding model, we might want to compare the two varieties on each day: <<>>= org.vardiff <- update(pairs(org.mlsm, by = "day"), by = NULL) @ The results (not yet shown) will comprise the six "sales1-sales2" differences, one for each day. The two "by" specifications seems odd, but the one in "pairs" specifies doing a separate comparison for each day, and the one in "update" asks that we convert it to one table with six rows, rather than 6 tables with one row each. Now, let's compare these differences to see if they vary from day to day. <<>>= cld(org.vardiff) @ There is little evidence of variety differences, nor that these differences vary from day to day. \section[Interfacing with multcomp]{Interfacing with \pkg{multcomp}} The \pkg{multcomp} package \citep{multc} supports more exacting corrections for simultaneous inference than are available in \lsm{}. Its "glht" (general linear hypothesis testing) function and associated \dqt{glht} class are similar in some ways to "lsmeans" and \dqt{lsmobj} objects, respectively. So we provide methods such as "as.glht" for working with "glht" so as to obtain ``exact'' inferences. To illustrate, let's compare some simultaneous confidence intervals using the two packages. %%%\begin{multicols}{2}\small First, using a Bonferroni correction on the LS~means for "day" in the "oranges" model: <<>>= confint(days.lsm, adjust = "bon") @ %%%\columnbreak And now using \pkg{multcomp}: <<>>= library("multcomp") confint(as.glht(days.lsm)) @ %%%\end{multicols} The latter intervals are somewhat narrower, which is expected since the Bonferroni method is conservative. The \lsm{} package also provides an "lsm" function that can be called as the second argument of "glht": <<>>= summary(glht(oranges.lm1, lsm("day", contr="eff")), test = adjusted("free")) @ An additional detail: If there is a "by" variable in effect, "glht" or "as.glht" returns a "list" of "glht" objects---one for each "by" level. There is a courtesy "summary" method for this \dqt{glht.list} class to make things a bit more user-friendly. Recall the earlier example result "org.lsm", which contains information for LS~means for three "day"s at each of two values of "price2". Suppose we are interested in pairwise comparisons of these LS~means, by "price2". If we call <>= summary(as.glht(pairs(org.lsm))) @ (results not displayed) we will obtain two "glht" objects with three contrasts each, so that the results shown will incorporate multiplicity adjustments for each family of three contrasts. If, on the other hand, we want to consider those six contrasts as one family, use <>= summary(as.glht(pairs(org.lsm), by = NULL)) @ \ldots{} and note (look carefully at the parentheses) that this is \emph{not} the same as <>= summary(as.glht(pairs(org.lsm, by = NULL))) @ which removes the "by" grouping \emph{before} the pairwise comparisons are generated, thus yielding ${6 \choose 2}=15$ contrasts instead of just six. \section{A new example: Oat yields} Orange-sales illustrations are probably getting tiresome. To illustrate some new features, let's turn to a new example. The "Oats" dataset in the \pkg{nlme} package \citep{nlme} has the results of a split-plot experiment discussed in \citet{Yat35}. The experiment was conducted on six blocks (factor "Block"). Each block was divided into three plots, which were randomized to three varieties (factor "Variety") of oats. Each plot was divided into subplots and randomized to four levels of nitrogen (variable "nitro"). The response, "yield", was measured once on each subplot after a suitable growing period. We will fit a model using the "lmer" function in the \pkg{lme4} package \citep{lme4}. This will be a mixed model with random intercepts for "Block" and "Block:Variety" (which identifies the plots). A logarithmic transformation is applied to the response variable (mostly for illustration purposes, though it does produce a good fit to the data). Note that "nitro" is stored as a numeric variable, but we want to consider it as a factor in this initial model. <<>>= data("Oats", package = "nlme") library("lme4") Oats.lmer <- lmer(log(yield) ~ Variety*factor(nitro) + (1|Block/Variety), data = Oats) anova(Oats.lmer) @ Apparently, the interaction is not needed. But perhaps we can further simplify the model by using only a linear or quadratic trend in "nitro". We can find out by looking at polynomial contrasts: <>= contrast(lsmeans(Oats.lmer, "nitro"), "poly") @ %%% Fake the warning message <>= cat("NOTE: Results may be misleading due to involvement in interactions") @ <>= <> @ (A message is issued when we average over predictors that interact with those that delineate the LS~means. In this case, it is not a serious problem because the interaction is weak.) Both the linear and quadratic contrasts are pretty significant. All this suggests fitting an additive model where "nitro" is included as a numeric predictor with a quadratic trend. <<>>= Oats.lmer2 <- lmer(log(yield) ~ Variety + poly(nitro,2) + (1|Block/Variety), data = Oats) @ Remember that "nitro" is now used as a quantitative predictor. But for comparing with the previous model, we want to see predictions at the four unique "nitro" values rather than at the average of "nitro". This may be done using "at" as illustrated earlier, or a shortcut is to specify "cov.reduce" as "FALSE", which tells "ref.grid" to use all the unique values of numeric predictors. <<>>= Oats.lsm2 <- lsmeans(Oats.lmer2, ~ nitro | Variety, cov.reduce = FALSE) Oats.lsm2 @ These LS~means follow the same quadratic trend for each variety, but with different intercepts. Fractional degrees of freedom are displayed in these results. These are obtained from the \pkg{pbkrtest} package \citep{pbkrt}, and they use the Kenward-Rogers method. (The degrees of freedom for the polynomial contrasts were also obtained from \pkg{pbkrtest}, but the results turn out to be integers.) \section{Displaying LS means graphically} We have already seen the use of the "plot" function to display confidence intervals and/or comparison arrows. The \lsm{} package also includes a function "lsmip" that displays predictions in an interaction-plot-like manner. It uses a formula of the form \begin{Sinput} curve.factors ~ x.factors | by.factors \end{Sinput} This function also requires the \pkg{lattice} package. In the above formula, "curve.factors" specifies factor(s) used to delineate one displayed curve from another (i.e., groups in \pkg{lattice}'s parlance). "x.factors" are those whose levels are plotted on the horizontal axis. And "by.factors", if present, break the plots into panels. To illustrate, consider the first model we fitted to the "Oats" data. Let's do a graphical comparison of the two models we have fitted to the "Oats" data. <>= lsmip(Oats.lmer, Variety ~ nitro, ylab = "Observed log(yield)") @ \vspace{-12pt} <>= lsmip(Oats.lsm2, Variety ~ nitro, ylab = "Predicted log(yield)") @ The plots are shown in \Fig{intplots}. Note that the first model fits the cell means perfectly, so its plot is truly an interaction plot of the data. The other displays the parabolic trends we fitted in the revised model. \begin{figure} \includegraphics[width=3in]{using-lsmeans-oatslmer.pdf} \hfill \includegraphics[width=3in]{using-lsmeans-oatslmer2.pdf} \caption{Interaction plots for the cell means and the fitted model, \code{Oats} example.}\label{intplots} \end{figure} \section{Transformations} When a transformation or link function is used in fitting a model, "ref.grid" (also called by "lsmeans") stores that information in the returned object, as seen in this example: <<>>= str(Oats.lsm2) @ This allows us to conveniently unravel the transformation, via the "type" argument in "summary" or related functions such as "lsmip" and "predict". Here are the predicted yields for (as opposed to predicted log yields) for the polynomial model: <<>>= summary(Oats.lsm2, type = "response") @ It is important to realize that the statistical inferences are all done \emph{before} reversing the transformation. Thus, $t$ ratios are based on the linear predictors and will differ from those computed using the printed estimates and standard errors. Likewise, confidence intervals are computed on the linear-predictor scale, then the endpoints are back-transformed. This kind of automatic support for transformations is available only for certain standard transformations, namely those supported by the "make.link" function in the \pkg{stats} package. Others require more work---see the documentation for "update" for details. \section{Trends} The \lsm{} package provides a function \code{lstrends} for estimating and comparing the slopes of fitted lines (or curves). To illustrate, consider the built-in R dataset \code{ChickWeight} which has data on the growths of newly hatched chicks under four different diets. The following code produces the display in \Fig{chick-plot}. <>= xyplot(weight~Time | Diet, groups = ~ Chick, data=ChickWeight, type="o", layout=c(4,1)) @ \begin{figure} \centerline{\includegraphics[width=6in]{using-lsmeans-chick-plot}} \caption{Growth curves of chicks, dataset \texttt{ChickWeight}.}\label{chick-plot} \end{figure} Let us fit a model to these data using random slopes for each chick and allowing for a different average slope for each diet: <<>>= Chick.lmer <- lmer(weight ~ Diet * Time + (0 + Time | Chick), data = ChickWeight) @ We can then call "lstrends" to estimate and compare the average slopes for each diet. <<>>= ( Chick.lst <- lstrends (Chick.lmer, ~ Diet, var = "Time") ) @ Here we obtain estimates and pairwise comparisons of the slopes using a compact letter display. <<>>= cld (Chick.lst) @ According to the Tukey~HSD comparisons (with default significance level of $.05$), there are two groupings of slopes: Diet~1's mean slope is significantly less than $3$ or $4$'s, Diet~2's slope is not distinguished from any other. Note: "lstrends" computes a difference quotient based on two slightly different reference grids. Thus, it must be called with a model object, not a "ref.grid" object. \section{User preferences} \lsm{} sets certain defaults for displaying results---for example, using $.95$ for the confidence coefficient, and showing intervals for "lsmeans" output and test statistics for "contrast" results. As discussed before, one may use arguments in "summary" to change what is displayed, or "update" to change the defaults for a given object. But suppose you want different defaults to begin with. These can be set using the "lsm.options" statement. For example: <<>>= lsm.options(ref.grid = list(level = .90), lsmeans = list(), contrast = list(infer = c(TRUE,TRUE))) @ This requests that any object created by "ref.grid" be set to have confidence levels default to $90$\%, and that "contrast" results are displayed with both intervals and tests. No new options are set for "lsmeans" results, and the "lsmeans" part could have been omitted. These options are stored with objects created by "ref.grid", "lsmeans", and "contrast". For example, even though no new defaults are set for "lsmeans", future calls to "lsmeans" \emph{on a model object} will be displayed with 90\% confidence intervals, because "lsmeans" calls "ref.grid". However, calling "lsmeans" on an existing \dqt{ref.grid} object will inherit that object's setting. \section{Two-sided formulas} In its original design, the only way to obtain contrasts and comparisons in \lsm{} was to specify a two-sided formula, e.g., "pairwise ~ treatment", in the "lsmeans" call. The result is then a list of "lsmobj" objects. In its newer versions, \lsm{} offers a richer family of objects that can be re-used, and dealing with a list of objects can be awkward or confusing, so its continued use is not encouraged. Nonetheless, it is still available for backward compatibility. Here is an example where, with one command, we obtain both the LS~means and pairwise comparisons for "Variety" in the model "Oats.lmer2": {\small <<>>= lsmeans(Oats.lmer2, pairwise ~ Variety) @ } This example also illustrates the effect of the preceding "lsm.options" settings. Let us now return to the default display for contrast results. <<>>= lsm.options(ref.grid = NULL, contrast = NULL) @ \section{Messy data} To illustrate some more \code{lsmeans} capabilities, consider the dataset named \code{nutrition} that is provided with the \lsm{} package. These data come from \citet{Mil92}, and contain the results of an observational study on nutrition education. Low-income mothers are classified by race, age category, and whether or not they received food stamps (the \code{group} factor); and the response variable is a gain score (post minus pre scores) after completing a nutrition training program. Consider the model that includes all main effects and two-way interactions. A Type-II (hierarchical) analysis-of-variance table is also shown. <<>>= nutr.lm <- lm(gain ~ (age + group + race)^2, data = nutrition) library("car") Anova(nutr.lm) @ One main effect ("group") is quite significant, and there is possibly an interaction with "race". Let us look at the \code{group} by \code{race} LS~means: <>= lsmip(nutr.lm, race ~ age | group) lsmeans(nutr.lm, ~ group*race) @ \begin{figure} \centerline{\includegraphics[scale=.75]{using-lsmeans-nutr-intplot}} \caption{Predictions for the nutrition data}\label{nutr-intplot} \end{figure} \Fig{nutr-intplot} shows the predictions from this model. One thing the output illustrates is that \code{lsmeans} incorporates an estimability check, and returns a missing value when a prediction cannot be made uniquely. In this example, we have very few Hispanic mothers in the dataset, resulting in empty cells. This creates a rank deficiency in the fitted model, and some predictors are thrown out. We can avoid non-estimable cases by using \code{at} to restrict the reference levels to a smaller set. A useful summary of the results might be obtained by narrowing the scope of the reference levels to two races and the two middle age groups, where most of the data lie. However, always keep in mind that whenever we change the reference grid, we also change the definition of the LS~means. Moreover, it may be more appropriate to average the two ages using weights proportional to their frequencies in the data set. The simplest way to do this is to add a "weights" argument.\footnote{ It may also be done by specifying a custom function in the \code{fac.reduce} argument, but for simple weighting, \code{weights} is simpler.} With those ideas in mind, here are the LS~means and comparisons within rows and columns: <<>>= nutr.lsm <- lsmeans(nutr.lm, ~ group * race, weights = "proportional", at = list(age = c("2","3"), race = c("Black","White"))) @ So here are the results <<>>= nutr.lsm summary(pairs(nutr.lsm, by = "race"), by = NULL) summary(pairs(nutr.lsm, by = "group"), by = NULL) @ The general conclusion from these analyses is that for age groups 2 and~3, the expected gains from the training are higher among families receiving food stamps. Note that this analysis is somewhat different than the results we would obtain by subsetting the data before analysis, as we are borrowing information from the other observations in estimating and testing these LS~means. \subsection{More on weighting}\label{weights} The "weights" argument can be a vector of numerical weights (it has to be of the right length), or one of four text values: \dqt{equal} (weight the predictions equally when averaging them, the default), \dqt{proportional} (weight them proportionally to the observed frequencies of the factor combinations being averaged over), \dqt{outer} (weight according to the outer products of the one-factor marginal counts), or \dqt{cells} (weight each mean differently, according to the frequencies of the predictions being averaged). \Fig{wtcomp} shows the LS~means for "race" using the four different weighting schemees. \begin{figure} \hspace{-.06\linewidth} \begin{minipage}{1.12\linewidth} \hrule \columnseprule=.2pt \begin{multicols}{2}\footnotesize <<>>= lsmeans(nutr.lm, "race", weights = "equal") lsmeans(nutr.lm, "race", weights = "prop") lsmeans(nutr.lm, "race", weights = "outer") lsmeans(nutr.lm, "race", weights = "cells") @ \end{multicols} \hrule \end{minipage} \caption{Comparison of four different weighting methods}\label{wtcomp} \end{figure} Note there are four different sets of answers. The \dqt{equal} weighting is self-explanatory. But what's the distinction between \dqt{proportional} and \dqt{outer}? To clarify, consider: <<>>= temp = lsmeans(nutr.lm, c("group","race"), weights = "prop") lsmeans(temp, "race", weights = "prop") @ The previous results using \dqt{outer} weights are the same as those using \dqt{proportional} weights on one factor at a time. Thus, if only one factor is being averaged over, \dqt{outer} and \dqt{proportional} are the same. Another way to look at it is that outer weights are like the expected counts in a chi-square test; each factor is weighted independently of the others. The results for \dqt{cells} weights stand out because everything is estimable---that's because the empty cells in the data were given weight zero. These results are the same as the unadjusted means: <<>>= with(nutrition, tapply(gain, race, mean)) @ \subsection{Alternative covariate adjustments} The "framing" data in the \pkg{mediation} package has the results of an experiment conducted by \cite{Bra08} where subjects were given the opportunity to send a message to Congress regarding immigration. However, before being offered this, some subjects ("treat=1") were first shown a news story that portrays Latinos in a negative way. Besides the binary response (whether or not they elected to send a message), we also measured "emp", the subjects' emotional state after the treatment was applied. There are various demographic variables as well. Before fitting a logistic regression model, I will change the labels for educ to shorter strings. <<>>= library("mediation") levels(framing$educ) = c("NA","Ref","< HS", "HS", "> HS","Coll +") framing.glm = glm(cong_mesg ~ age + income + educ + emo + gender * factor(treat), family = binomial, data = framing) @ The left-hand plot in \Fig{framing} displays the conventional adjusted means, where predictions are made with the covariates "age", "income", and "emo" set to their mean values: <>= lsmip(framing.glm, treat ~ educ | gender, type = "response") @ This plot is rather implausible because the displayed treatment effects are the opposite for females as for males, and the effect of education isn't monotone as one might expect. \begin{figure} \begin{center} \begin{tabular}{c@{\qquad}c} (a) & (b) \\ \includegraphics[width=3in]{using-lsmeans-framinga.pdf} & \includegraphics[width=3in]{using-lsmeans-framingb.pdf} \end{tabular} \end{center} \caption{Estimated responses for the \code{framing} data. (a)~Holding \code{emo} constant at its mean; (b)~Using predictions of \code{emo} for each \code{treat}.}\label{framing} \end{figure} However, "emo" is a post-treatment measurement. This means that the treatment could have affected it (it is a \emph{mediating} covariate). If it is indeed affected by "treat", then \Fig{framing}(a) would be misleading because "emo" is held constant. Instead, consider making the predictions where "emo" is set to its predicted value at each combination of "treat" and the demographic variables. This is easily done by setting "cov.reduce" to a formula for how to predict "emo": <>= lsmip(framing.glm, treat ~ educ | gender, type = "response", cov.reduce = emo ~ treat*gender + age + educ + income) @ This plot is shown in \Fig{framing}(b). It is quite different, suggesting that "emo" does indeed play a strong mediating role. (The \pkg{mediation} package has functions for estimating the strength of these effects.) The predictions suggest that, taking emotional response into account, male subjects exposed to the negative news story are more likely to send the message than are females or those not seeing the negative news story. Also, the effect of "educ" is (almost) monotone. You can see what values of "emo" are used in these predictions by looking at the "grid" slot in the reference grid: <<>>= ref.grid(framing.glm, cov.reduce = emo ~ treat*gender + age + educ + income)@grid @ whereas the overall mean of \Sexpr{round(mean(framing$emo), 3)} is used as the value of "emo" in \Fig{framing}(a). \ifx %%% Old covariate example is commented-out %%%%%%%%%%%%%%%%%% \cite{urq82} reports data on slaughter weights of animals that entered a feedlot as yearling calves. The animals came from 11 different herds, and each animal was randomized to one of three diets. In addition, the weight of each yearling at entry was recorded. The "feedlot" dataset provided in \lsm{} contains these results. From the feedlot operator's perspective, both diets and herds are fixed effects. Let us fit a factorial model with slaughter weight "swt" as the response and entry weight "ewt" as a covariate. %<<>>= feedlot.lm <- lm(swt ~ ewt + herd * diet, data = feedlot) Anova(feedlot.lm) @ The interaction tesrm doesn't make much of a contribution here, so we will work with an additive model instead (which also ameliorates some non-estimability issues due to missing cells). %<<>>= feedlot.add <- update(feedlot.lm, . ~ . - herd:diet) @ Here are the "LS~means" for the herds, and a compact letter display for comparisons thereof: %<<>>= cld(lsmeans(feedlot.add, "herd")) @ No herds are found to be different---not a surprise given that the $P$~value for "herd" is about the same as for the original model. However, these predictions are made at the same entry weight for every herd. This is \emph{not} the right thing to do here, because the herds differ in genetic makeup, the way they were fed and managed, and so forth---which affect the yearlings' entry weights. This is an example where a treatment affects a covariate. Each herd should have its own reference value for entry weight. This is done in "lsmeans" by providing a formula in the "cov.reduce" argument. The formula "ewt ~ herd" indicates that the reference grid should be constructed using the predicted value of "ewt", based on a linear model with "herd" as the predictor. Here are the results: %<<>>= cld(lsmeans(feedlot.add, "herd", cov.reduce = ewt ~ herd)) @ What a world of difference! We now see many significant differences in the comparisons. By the way, another approach would be to simply omit "ewt" from the model, to prevent making inappropriate adjustments in the traditional analysis. With such a model (not shown), the predictions are similar to those above; however, their standard errors are substantially higher, because---as seen in the ANOVA table---the covariate explains a lot of the variation. \fi %%%%%%%%%%%%% end of commented-out section %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Another use of formulas in "cov.reduce" is to create representative values of some covariates when others are specified in "at". For example, suppose there are three covariates $x_1,x_2,x_3$ in a model, and we want to see predictions at a few different values of $x_1$. We might use <>= rg <- ref.grid(my.model, at = list(x1 = c(5,10,15)), cov.reduce = list(x2 ~ x1, x3 ~ x1 + x2)) @ (When more than one formula is given, they are processed in the order given.) The values used for $x_2$ and $x_3$ will depend on $x_1$ and should in some sense be more realistic values of those covariates as $x_1$ varies than would be the overall means of $x_2$ and $x_3$. Of course, it would be important to display the values used---available as "rg@grid"---when reporting the analysis. \section{Other types of models} \subsection[Models supported by lsmeans]{Models supported by \lsm{}} The \lsm{} package comes with built-in support for several packages and model classes: \begin{quote} \begin{description} \pitem{stats}: \dqt{lm}, \dqt{mlm}, \dqt{aov}, \dqt{aovlist}, \dqt{glm} \pitem{nlme}: \dqt{lme}, \dqt{gls} \pitem{lme4}: \dqt{lmerMod}, \dqt{glmerMod} \pitem{survival}: \dqt{survreg}, \dqt{coxph} \pitem{coxme}: \dqt{coxme} \pitem{MASS}: \dqt{polr} \pitem{gee, geepack}: \dqt{gee}, \dqt{geeglm}, \dqt{geese} \end{description} \end{quote} \lsm{} support for all these models works similarly to the examples we have presented. Note that generalized linear or mixed models, and several others such as survival models, typically employ link functions such as "log" or "logit". In all such cases, the LS~means displayed are on the scale of the linear predictor, and any averaging over the reference grid is performed on the linear-predictor scale. Results for \code{aovlist} objects are based on intra-block estimates, and should be used with caution. \subsection{Proportional-odds example} There is an interesting twist in \dqt{polr} objects (polytomous regression for Likert-scale data), in that an extra factor (named \dqt{cut} by default) is created to identify which boundary between scale positions we wish to use in predictions. The example here is based on the "housing" data in the \pkg{MASS} package, where the response variable is satisfaction ("Sat") on a three-point scale of low, medium, high; and predictors include "Type" (type of rental unit, four levels), "Infl" (influence on management of the unit, three levels), and "Cont" (contact with other residents, two levels). Here, we fit a (not necessarily good) model and obtain LS~means for "Infl" <<>>= library("MASS") housing.plr <- polr(Sat ~ Infl + Type + Cont, data = housing, weights = Freq) ref.grid(housing.plr) housing.lsm <- lsmeans(housing.plr, ~ Infl | cut) @ The default link function is "logit". Now we transform the predictions and contrasts thereof to the response scale: <<>>= summary(housing.lsm, type = "response") summary(pairs(housing.lsm), type = "response") [1:3, ] @ The logits are transformed to cumulative probabilities (note that a low cumulative probability means a low number of people are dissatisfied; thus, we find that those having more influence tend to me more satisfied). Note also that the pairwise comparisons transform to odds ratios. Only the first three rows of the comparisons table are shown because the results for "cut = Medium|High" will be identical. Another point worth noting is that when only asymptotic tests and confidence intervals are available, degrees of freedom are set to "NA", and test statistics and intervals are labeled differently. \subsection{Extending to more models} The functions "ref.grid" and "lsmeans" work by first reconstructing the dataset (so that the reference grid can be identified) and extracting needed information about the model, such as the regression coefficients, covariance matrix, and the linear functions associated with each point in the reference grid. For a fitted model of class, say, \dqt{modelobj}, these tasks are accomplished by defining S3 methods "recover.data.modelobj" and "lsm.basis.modelobj". The help page \dqt{extending-lsmeans} and the vignette by the same name provide details and examples. Developers of packages that fit models are encouraged to include support for \lsm{} by incorporating (and exporting) "recover.data" and "lsm.basis" methods for their model classes. \section{Discussion} The design goal of \lsm{} is primarily to provide the functionality of the "LSMEANS" statement in various \SAS{} procedures. Thus its emphasis is on tabular results which, of course, may also be used as data for further analysis or graphics. By design, it can be extended with relative ease to additional model classes. A unique capability of \lsm{} is its explicit reliance on the concept of a reference grid, which I feel is a useful approach for understanding what is being computed. Some \lsm{} capabilities exceed those of \SAS, including the "lstrends" capability, more flexibility in organizing the output, and more built-in contrast families. In addition, \SAS{} does not allow LS~means for factor combinations when the model does not include the interaction of those factors; or creating a grid of covariate values using "at". There are a few other \R{} packages that provide capabilities that overlap with those of \lsm{}. The \pkg{effects} package \citep{effects,fox09} can compute LS~means. However, for an unbalanced dataset, it does not use equal weights, but rather it appears to use ``outer'' weights, as described in Section~\ref{weights}. Also, it does not check estimability, so some results could be questionable. The emphasis of \pkg{effects} is on graphical rather than tabular displays. It has special strengths for curve-fitting models such as splines. In contrast, \lsm{}'s strengths are more in the area of factorial models where one wants traditional summaries in the form of estimates, contrasts, and interaction plots. The \pkg{doBy} package \citep{doBy} provides an "LSmeans" function that has some of the capabilities of "lsmeans", but it produces a data frame rather than a reusable object. In earlier versions of the package, this function was named "popMeans". The package also has an "LSmatrix" function to obtain the linear functions needed to obtain LS~means. \bibliography{lsmeans}\bibliographystyle{jss} \end{document}