I am using r 3.3.3, dplyr 0.7.4, and Hmisc 4.1-1. I noticed that the order I load packages effects whether or not a dplyr::summaries function wold work or not. I understand that
UPDATE: As of haven version 2.0.0 this issue has been resolved, as the haven "labelled" class was renamed to "haven_labelled" to avoid conflicts with Hmisc.
tl;dr: Order matters.
For a more detailed answer, let's first reproduce the error:
library(Hmisc)
#> Loading required package: lattice
#> Loading required package: survival
#> Loading required package: Formula
#> Loading required package: ggplot2
#>
#> Attaching package: 'Hmisc'
#> The following objects are masked from 'package:base':
#>
#> format.pval, units
library(tidyverse)
#> Warning: package 'forcats' was built under R version 3.4.4
After removing elements piece by piece from the original summarise example,
I managed to reduce reproducing the error to just these lines of code:
Hmisc::label(iris$Petal.Width) <- "Petal Width"
head(iris)
#> Error: `x` and `labels` must be same type
We can have a look at the traceback to see if we can locate a function that could be causing the error:
traceback()
#> 8: stop("`x` and `labels` must be same type", call. = FALSE)
#> 7: labelled(NextMethod(), attr(x, "labels"))
#> 6: `[.labelled`(xj, i)
#> 5: xj[i]
#> 4: `[.data.frame`(x, seq_len(n), , drop = FALSE)
#> 3: x[seq_len(n), , drop = FALSE]
#> 2: head.data.frame(iris)
#> 1: head(iris)
The [.labelled call looks suspicious. Why is it even called?
lapply(iris, class)
#> $Sepal.Length
#> [1] "numeric"
#>
#> $Sepal.Width
#> [1] "numeric"
#>
#> $Petal.Length
#> [1] "numeric"
#>
#> $Petal.Width
#> [1] "labelled" "numeric"
#>
#> $Species
#> [1] "factor"
Ah, setting a label for Petal.Width with Hmisc::label also added the S3 class.
We can inspect where the method is defined with getAnywhere:
getAnywhere("[.labelled")
#> 2 differing objects matching '[.labelled' were found
#> in the following places
#> registered S3 method for [ from namespace haven
#> namespace:Hmisc
#> namespace:haven
#> Use [] to view one of them
Indeed, both haven and Hmisc define the method. And since haven is
loaded after Hmisc, its definition is found first, and thus gets used:
getAnywhere("[.labelled")[1]
#> function (x, ...)
#> {
#> labelled(NextMethod(), attr(x, "labels"))
#> }
#> <environment: namespace:haven>
haven expects labelled objects to have a labels attribute, which
Hmisc::label doesn't create:
attr(iris$Petal.Width, "labels")
#> NULL
And that's where the error comes from.
haven even loaded? It's not attached with library(tidyverse).
Turns out, that haven is listed as an imported package in tidyverse,
which causes it to be loaded when the package is attached (see e.g.
here). And loading a package,
among other things, registers its S3 methods: which is where the conflict
comes from.
As it is, if you want to use both Hmisc and tidyverse, order matters.
To address the issue further would likely require source level changes in
the packages' use of the labelled S3 class.
Created on 2018-03-21 by the reprex package (v0.2.0).