在 Hmisc 之后加载 tidyverse 时的评估错误
Evaluation Error when tidyverse is loaded after Hmisc
我正在使用 r 3.3.3、dplyr 0.7.4 和 Hmisc 4.1-1。我注意到我加载包的顺序会影响 dplyr::summaries 函数是否工作。我知道以不同的顺序加载包会掩盖某些功能,但我使用 package::function() 语法来避免该问题。确切的问题围绕着标记变量。我知道过去 tidyverse 和变量标签存在问题,但 none 似乎解决了为什么会出现这种特殊情况。
第一个有效的例子 - 我只加载 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() 语法但这会引发错误:
Error in summarise_impl(.data, dots) : Evaluation error: x
and
labels
must be same type.
第二个例子:
###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 version 3.3.3 (2017-03-06)
Running under: Windows 7 x64
attached base packages: [1] stats graphics grDevices utils datasets methods base
其他附包:[1]bindrcpp_0.2forcats_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 Formula_1.2-2 [13] survival_2.41-3 lattice_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.1 foreign_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
munsell_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 parallel_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 digest_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 数据.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
更新: 自 haven version 2.0.0 起,此问题已得到解决,因为天堂 "labelled" class 已重命名为 "haven_labelled"
以避免与杂项.
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)
[.labelled
电话看起来很可疑。为什么叫它?
lapply(iris, class)
#> $Sepal.Length
#> [1] "numeric"
#>
#> $Sepal.Width
#> [1] "numeric"
#>
#> $Petal.Length
#> [1] "numeric"
#>
#> $Petal.Width
#> [1] "labelled" "numeric"
#>
#> $Species
#> [1] "factor"
啊,用Hmisc::label
给Petal.Width
设置了标签,还加了S3class。
我们可以检查方法定义的位置 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
和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
这就是错误的来源。
但是等等: 为什么 haven
甚至加载了?它没有附加 library(tidyverse)
。
事实证明,haven
是 tidyverse
中的 listed as an imported package,
这导致它在附加包裹时被加载(参见例如
here)。并加载一个包,
除其他事项外,注册其 S3 方法:这是冲突的地方
来自.
实际上,如果您想同时使用 Hmisc
和 tidyverse
,顺序很重要。
要进一步解决该问题,可能需要更改源代码级别
软件包对 labelled
S3 class.
的使用
由 reprex package (v0.2.0) 创建于 2018-03-21。
我正在使用 r 3.3.3、dplyr 0.7.4 和 Hmisc 4.1-1。我注意到我加载包的顺序会影响 dplyr::summaries 函数是否工作。我知道以不同的顺序加载包会掩盖某些功能,但我使用 package::function() 语法来避免该问题。确切的问题围绕着标记变量。我知道过去 tidyverse 和变量标签存在问题,但 none 似乎解决了为什么会出现这种特殊情况。
第一个有效的例子 - 我只加载 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() 语法但这会引发错误:
Error in summarise_impl(.data, dots) : Evaluation error:
x
andlabels
must be same type.
第二个例子:
###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 version 3.3.3 (2017-03-06) Running under: Windows 7 x64 attached base packages: [1] stats graphics grDevices utils datasets methods base
其他附包:[1]bindrcpp_0.2forcats_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 Formula_1.2-2 [13] survival_2.41-3 lattice_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.1 foreign_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
munsell_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 parallel_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 digest_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 数据.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
更新: 自 haven version 2.0.0 起,此问题已得到解决,因为天堂 "labelled" class 已重命名为 "haven_labelled"
以避免与杂项.
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)
[.labelled
电话看起来很可疑。为什么叫它?
lapply(iris, class)
#> $Sepal.Length
#> [1] "numeric"
#>
#> $Sepal.Width
#> [1] "numeric"
#>
#> $Petal.Length
#> [1] "numeric"
#>
#> $Petal.Width
#> [1] "labelled" "numeric"
#>
#> $Species
#> [1] "factor"
啊,用Hmisc::label
给Petal.Width
设置了标签,还加了S3class。
我们可以检查方法定义的位置 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
和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
这就是错误的来源。
但是等等: 为什么
haven
甚至加载了?它没有附加 library(tidyverse)
。
事实证明,haven
是 tidyverse
中的 listed as an imported package,
这导致它在附加包裹时被加载(参见例如
here)。并加载一个包,
除其他事项外,注册其 S3 方法:这是冲突的地方
来自.
实际上,如果您想同时使用 Hmisc
和 tidyverse
,顺序很重要。
要进一步解决该问题,可能需要更改源代码级别
软件包对 labelled
S3 class.
由 reprex package (v0.2.0) 创建于 2018-03-21。