Transitioning to emmeans from lsmeans

Russ Lenth



emmeans is a continuation of the lsmeans package. The name is changed for two reasons:

  1. The term “least-squares means” is misleading in terms of describing the analyses it provides. The term “estimated marginal means” (EMMs) is well-accepted, and it better describes the basic idea that we use marginal means of predictions over a reference grid. When we do that with, say, an ordinal model, the concept “estimated marginal mean” makes sense while “least-squares mean” does not, because no least-squares methods are used to fit the model or obtain the EMMs.
  2. A number of changes are made to the internal architecture of the package. The lsmeans package had two classes, ref.grid and lsmobj, and it was confusing to some users that they needed to use primarily ref.grid methods to summarize lsmobj objects. The emmeans package has only an emmGrid class that covers both of the old classes. Changing the name of the package at the same time as the object classes are changed makes for a cleaner transition.

User impact

For the most part, all that most users need to do to transition from using the lsmeans package is to use require(emmeans) or library(emmeans) to load the package. With that one change, almost all of the code in the using-lsmeans vignette runs without alteration, and almost all examples from the help system for lsmeans also work as-is. Even though we now emphasize using the emmeans() function and related “em” functions, lsmeans() and its relatives are still available as wrappers for the new functions.

That said, here are a few changes that former lsmeans users may need to be aware of:

Converting scripts

The user may run


to convert R scripts or R Markdown files to use emmeans functions. (This is a non-exported function – you need three :s in there.)

The conversion routines will convert the following to their emmeans counterparts:

Converting workspaces

If you have any objects from the lsmeans package laying around, it is all too likely that the lsmeans package will be loaded, and perhaps even get added to the search path. This can create annoying messages, if not conflicts. When this happens, type


on the console. This will convert any ref.grid or lsmobj objects laying around to the new emmGrid class, and unload all vestiges of lsmeans.

Once you are comfortable using emmeans in place of lsmeans, you may effect a permanent solution (the “nuclear option?”) by uninstalling the lsmeans package. Doing so will not prevent you from converting old workspaces or scripts. Watch your package updates carefully, though, as it may get re-installed if it is still imported by another package.

Notes for package developers to transition to emmeans support

if you are the developer of a package that supports lsmeans, and you want to transition to supporting emmeans, I make the following suggestions:

  1. Currently, your package provides methods and, where xyz stands in for the class of your object. Rename these functions and
  2. Any calls to lsmeans:: functions in the above methods should be changed to the corresponding emmeans:: functions.
  3. For a period of time, you may want to continue support for lsmeans as well. So write new functions and that just call their counterparts.
  4. In your DESCRIPTION file, add emmeans to Imports, and make sure that lsmeans is not in Imports.
  5. In your NAMESPACE file,
    1. add importFrom(emmeans, recover_data, emm_basis)
    2. add S3method(recover_data, xyz)
    3. add S3method(emm_basis, xyz)
    4. add export(, That is, export them as functions, and not as S3 methods
    5. In lieu of (a)-(c) above, you could just export the functions and

  1. Many of the deprecated functions, like ref.grid(), are renamed to avoid possible confusion in S3 method dispatch: how do we know that summary.ref.grid() wasn’t a summary.ref() method for class grid, rather than a summary() method for class ref.grid?

  2. By the way, the pmmeans(), pmmip(), etc. wrappers already provided in lsmeans are also still available.