【问题标题】:Reordering factor gives different results, depending on which packages are loaded重新排序因子会给出不同的结果,具体取决于加载的包
【发布时间】:2012-06-11 23:05:39
【问题描述】:

我想创建一个条形图,其中条形按高度而不是按字母顺序按类别排序。当我加载的唯一包是 ggplot2 时,这很好用。但是,当我加载更多包并运行创建、排序和绘制数据框的相同代码时,条形图又恢复为按字母顺序排序。

我每次都使用str() 检查数据框,结果发现数据框的属性现在不同了,即使我每次都运行相同的代码。

我的代码和输出如下所示。谁能解释不同的行为?为什么加载一些明显不相关的包(在某种意义上说我正在使用的函数似乎都没有被新加载的包掩盖)会改变运行transform() 函数的结果?

案例 1:只加载了 ggplot2

library(ggplot2)

group = c("C","F","D","B","A","E")
num = c(12,11,7,7,2,1)
data = data.frame(group,num)
data1 = transform(data, group=reorder(group,-num))

> str(data1)
'data.frame':   6 obs. of  2 variables:
 $ group: Factor w/ 6 levels "C","F","B","D",..: 1 2 4 3 5 6
  ..- attr(*, "scores")= num [1:6(1d)] -2 -7 -12 -7 -1 -11
  .. ..- attr(*, "dimnames")=List of 1
  .. .. ..$ : chr  "A" "B" "C" "D" ...
 $ num  : num  12 11 7 7 2 1

案例 2:加载多个包,然后再次运行相同的代码

library(plyr)
library(xtable)
library(Hmisc)
library(gmodels)
library(reshape2)
library(vcd)
library(lattice)

group = c("C","F","D","B","A","E")
num = c(12,11,7,7,2,1)
data = data.frame(group,num)
data1 = transform(data, group=reorder(group,-num))

> str(data1)
'data.frame':   6 obs. of  2 variables:
 $ group: Factor w/ 6 levels "A","B","C","D",..: 3 6 4 2 1 5
 $ num  : num  12 11 7 7 2 1

更新:SessionInfo()

案例1:加载ggplot2后运行sessionInfo()

> sessionInfo()
R version 2.15.0 (2012-03-30)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

locale:
  [1] C/en_US.UTF-8/C/C/C/C

attached base packages:
  [1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
  [1] ggplot2_0.9.1

loaded via a namespace (and not attached):
  [1] MASS_7.3-18        RColorBrewer_1.0-5 colorspace_1.1-1   dichromat_1.2-4    digest_0.5.2       grid_2.15.0       
[7] labeling_0.1       memoise_0.1        munsell_0.3        plyr_1.7.1         proto_0.3-9.2      reshape2_1.2.1    
[13] scales_0.2.1       stringr_0.6        tools_2.15.0

案例 2:加载附加包后运行 sessionInfo()

> sessionInfo()
R version 2.15.0 (2012-03-30)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

locale:
  [1] C/en_US.UTF-8/C/C/C/C

attached base packages:
  [1] grid      splines   stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
  [1] lattice_0.20-6   vcd_1.2-13       colorspace_1.1-1 MASS_7.3-18      reshape2_1.2.1   gmodels_2.15.2  
[7] Hmisc_3.9-3      survival_2.36-14 xtable_1.7-0     plyr_1.7.1       ggplot2_0.9.1   

loaded via a namespace (and not attached):
  [1] RColorBrewer_1.0-5 cluster_1.14.2     dichromat_1.2-4    digest_0.5.2       gdata_2.8.2        gtools_2.6.2      
[7] labeling_0.1       memoise_0.1        munsell_0.3        proto_0.3-9.2      scales_0.2.1       stringr_0.6       
[13] tools_2.15.0

【问题讨论】:

  • 你能提供sessionInfo()的输出吗?如果有人可以提供帮助,他们可能必须匹配您的 R 和包版本才能复制它。
  • 我可以使用最新的 CRAN 包(在 Ubuntu 上)在 R 2.15.0 上复制它
  • 非常有趣。看起来transform() 结果的变化仅在加载gmodels 后出现(并且随后分离gmodels 并没有修复它)。我很感兴趣...(FWIW,我在 Windows XP 上,运行 R-devel,所以看起来这不是操作系统或版本特定的问题。)
  • @joran 我添加了sessionInfo() 的输出作为对我的问题的编辑。
  • 您可以通过运行str 获得与大多数ggplot2 对象类似的行为,无论是否加载library(proto)。使用proto 大大扩展了proto 对象的显示范围。

标签: r namespaces masking operator-precedence


【解决方案1】:

发生这种情况是因为:

  1. gmodels 进口 gdata
  2. gdatareorder.factor 创建一个新方法

开始一个干净的会话。那么:

methods("reorder")
[1] reorder.default*    reorder.dendrogram*

现在加载gdata(或者加载gmodels,效果一样):

library(gdata)
methods("reorder")
[1] reorder.default*    reorder.dendrogram* reorder.factor 

注意没有掩码,因为reorder.factor 不存在于基础中

重新创建问题,但这次显式调用不同的包:

group = c("C","F","D","B","A","E")
num = c(12,11,7,7,2,1)
data = data.frame(group,num)

基础 R 版本(使用 reorder.default):

str(transform(data, group=stats:::reorder.default(group,-num)))
'data.frame':   6 obs. of  2 variables:
 $ group: Factor w/ 6 levels "C","F","B","D",..: 1 2 4 3 5 6
  ..- attr(*, "scores")= num [1:6(1d)] -2 -7 -12 -7 -1 -11
  .. ..- attr(*, "dimnames")=List of 1
  .. .. ..$ : chr  "A" "B" "C" "D" ...
 $ num  : num  12 11 7 7 2 1

gdata 版本(使用reorder.factor):

str(transform(data, group=gdata:::reorder.factor(group,-num)))
'data.frame':   6 obs. of  2 variables:
 $ group: Factor w/ 6 levels "A","B","C","D",..: 3 6 4 2 1 5
 $ num  : num  12 11 7 7 2 1

【讨论】:

  • 您可以使用gdata::reorder.factor 版本通过添加FUN=identity 参数获得“预期”订单:data1 = transform(data, group=reorder(group,-num,FUN=identity))
  • 只是为了确保我理解这里的教训:当你加载一个包时,你可以使用完全相同的代码获得不同的行为,即使在没有屏蔽的情况下,如果新包具有特定的方法到您的对象(在本例中为 reorder.factor),它“覆盖”了原本适用于您的对象的“顶级”方法(在本例中为通用 reorder)的行为。对吗?
  • @eipi10 是的,您的示例清楚地说明了这一点。关于术语的迂腐:reorder.factor 被调度而不是reorder.default(因此在某种意义上覆盖了以前的行为)。这是一个非常有趣的问题。谢谢。
  • 安德烈,感谢您清晰而详细的回答。 @BrianDiggs 感谢您展示如何恢复所需的行为。
  • 非常感谢大家。这个问题让我发疯。有什么方法可以为这个问题添加更多元数据以使其更容易被发现?至少有one other poor soul处于混乱状态:
猜你喜欢
  • 1970-01-01
  • 2019-01-12
  • 2022-10-12
  • 2022-07-22
  • 1970-01-01
  • 2018-12-22
  • 2014-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多