Hmisc 之后加载 tidyverse 时评估错误

2024-01-03

我正在使用 r 3.3.3、dplyr 0.7.4 和 Hmisc 4.1-1。我注意到加载包的顺序会影响 dplyr::summaries 函数是否工作。我知道以不同的顺序加载包会屏蔽某些函数,但我使用 package::function() 语法来避免这个问题。确切的问题围绕标记变量。我知道过去 tidyverse 和变量标签存在问题,但似乎没有一个能够解决为什么会发生这种特殊情况。

第一个有效的例子 - 我只加载 Hmisc,然后加载 dplyr,我能够总结数据 -

#this works fine
library(Hmisc)
library(dplyr)

Hmisc::label(iris$Petal.Width) <- "Petal Width"

sumpct <- iris %>% 
  dplyr::group_by(Species) %>% 
  dplyr::summarise(med =median(Petal.Width),A40 = round(100*ecdf(Petal.Width)(.40),1),
            A50 =round(100*ecdf(Petal.Width)(.50),1),
            mns = mean(Petal.Width),
            lowermean = mean(Petal.Width)-sd(Petal.Width),
            lowermedian = median(Petal.Width) - sd(Petal.Width))

下面的第二个例子中断了。我启动一个新会话并在 Hmisc 之后加载 tidyverse 并仍然使用 package::function() 语法,但这会引发错误:

summarise_impl(.data,dots) 中的错误:评估错误:x and labels必须是同一类型。

第二个例子:

###restart session 
#this example does not work

library(Hmisc)
library(tidyverse)


Hmisc::label(iris$Petal.Width) <- "Petal Width"

sumpct <- iris %>% 
  dplyr::group_by(Species) %>% 
  dplyr::summarise(med =median(Petal.Width),A40 = round(100*ecdf(Petal.Width)(.40),1),
                   A50 =round(100*ecdf(Petal.Width)(.50),1),
                   mns = mean(Petal.Width),
                   lowermean = mean(Petal.Width)-sd(Petal.Width),
                   lowermedian = median(Petal.Width) - sd(Petal.Width))

但是,第三个示例确实有效,我只需重新启动会话并在 Hmisc 之前加载 tidyverse

第三个例子:

###switch order of loading packages and this works

library(tidyverse)
library(Hmisc)


Hmisc::label(iris$Petal.Width) <- "Petal Width"

sumpct <- iris %>% 
  dplyr::group_by(Species) %>% 
  dplyr::summarise(med =median(Petal.Width),A40 = round(100*ecdf(Petal.Width)(.40),1),
                   A50 =round(100*ecdf(Petal.Width)(.50),1),
                   mns = mean(Petal.Width),
                   lowermean = mean(Petal.Width)-sd(Petal.Width),
                   lowermedian = median(Petal.Width) - sd(Petal.Width)) 

所以我的问题是,为什么当我使用 package::function() 语法(特别是关于标记变量和 tidyverse)时,加载包的顺序很重要?

更新:以下错误的会话信息:

sessionInfo()

R版本3.3.3 (2017-03-06) 运行环境:Windows 7 x64 附加的基础包: [1] 统计图形 grDevices utils 数据集 方法基础

其他附加包:[1]bindrcpp_0.2 forcats_0.3.0
stringr_1.3.0 dplyr_0.7.4 [5] purrr_0.2.4 readr_1.1.1
tidyr_0.8.0 tibble_1.4.2 [9] tidyverse_1.2.1 Hmisc_4.1-1
ggplot2_2.2.1 公式_1.2-2 [13] 生存_2.41-3 格子_0.20-35

通过命名空间加载(且未附加):[1] reshape2_1.4.3
splines_3.3.3 Haven_1.1.1 [4] colorspace_1.3-2
htmltools_0.3.6 base64enc_0.1-3 [7] rlang_0.2.0
pillar_1.2.1foreign_0.8-69 [10]glue_1.2.0
RColorBrewer_1.1-2 readxl_1.0.0 [13] modelr_0.1.1
plyr_1.8.4 bindr_0.1.1 [16] cellranger_1.1.0
孟塞尔_0.4.3 gtable_0.2.0 [19] rvest_0.3.2
htmlwidgets_1.0 psych_1.7.8 [22]latticeExtra_0.6-28 knitr_1.20 并行_3.3.3 [25] htmlTable_1.11.2
broom_0.4.3 Rcpp_0.12.16 [28] acepack_1.4.1
scales_0.5.0 backports_1.1.2 [31] checkmate_1.8.5
jsonlite_1.5 gridExtra_2.3 [34] mnormt_1.5-5
hms_0.4.2 摘要_0.6.15 [37] stringi_1.1.7
grid_3.3.3 cli_1.0.0 [40] tools_3.3.3
magrittr_1.5 lazyeval_0.2.1 [43] cluster_2.0.6
crayon_1.3.4 pkgconfig_2.0.1 [46] Matrix_1.2-12
xml2_1.2.0 data.table_1.10.4-3 [49] lubridate_1.7.3
assertthat_0.2.0 httr_1.3.1 [52] rstudioapi_0.7
R6_2.2.2 rpart_4.1-13 [55] nnet_7.3-12
nlme_3.1-131.1


UPDATE: As of haven版本2.0.0 https://github.com/tidyverse/haven/blob/master/NEWS.md#haven-200这个问题已经解决,因为避难所“labelled”类被重命名为"haven_labelled"以避免与Hmisc.


tl;dr:顺序很重要。

为了获得更详细的答案,我们首先重现该错误:

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

从原始内容中逐段删除元素后summarise例子, 我设法将错误重现减少为以下代码行:

Hmisc::label(iris$Petal.Width) <- "Petal Width"
head(iris)
#> Error: `x` and `labels` must be same type

我们可以查看回溯,看看是否可以找到可能导致错误的函数:

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电话看起来很可疑。为什么它甚至被称为?

lapply(iris, class)
#> $Sepal.Length
#> [1] "numeric"
#> 
#> $Sepal.Width
#> [1] "numeric"
#> 
#> $Petal.Length
#> [1] "numeric"
#> 
#> $Petal.Width
#> [1] "labelled" "numeric" 
#> 
#> $Species
#> [1] "factor"

啊,设置标签Petal.Width with Hmisc::label还添加了S3类。 我们可以检查该方法的定义位置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

确实,两者haven and Hmisc定义方法。自从haven是 之后加载Hmisc,它的定义首先被找到,因此被使用:

getAnywhere("[.labelled")[1]
#> function (x, ...) 
#> {
#>     labelled(NextMethod(), attr(x, "labels"))
#> }
#> <environment: namespace:haven>

haven期望labelled对象有一个labels属性,其中Hmisc::label不创建:

attr(iris$Petal.Width, "labels")
#> NULL

这就是错误的来源。


But wait: why is haven even loaded? It's not attached with library(tidyverse). Turns out, that haven is listed as an imported package https://github.com/tidyverse/tidyverse/blob/master/DESCRIPTION in tidyverse, which causes it to be loaded when the package is attached (see e.g. here http://r-pkgs.had.co.nz/namespace.html). And loading a package, among other things, registers its S3 methods: which is where the conflict comes from.

事实上,如果您想同时使用两者Hmisc and tidyverse,顺序很重要。 要进一步解决该问题可能需要更改源级别 包的使用labelledS3级。

创建于 2018-03-21代表包 http://reprex.tidyverse.org(v0.2.0)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hmisc 之后加载 tidyverse 时评估错误 的相关文章

随机推荐