Коэффициент переупорядочивания дает разные результаты в зависимости от того, какие пакеты загружены

Я хотел создать гистограмму, в которой столбцы упорядочены по высоте, а не в алфавитном порядке по категориям. Это работало нормально, когда единственным загруженным пакетом был 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: запуск sessionInfo() после загрузки ggplot2

> 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

person eipi10    schedule 07.06.2012    source источник
comment
Не могли бы вы предоставить вывод sessionInfo()? Если кто-то может помочь, ему, возможно, придется сопоставить ваши версии R и пакета, чтобы воспроизвести это.   -  person joran    schedule 08.06.2012
comment
Я могу воспроизвести это на R 2.15.0 с последними пакетами CRAN (в Ubuntu)   -  person Justin    schedule 08.06.2012
comment
Очень интересно. Похоже, изменение результатов transform() проявляется только после загрузки gmodels (и не фиксируется последующим отсоединением gmodels). Я заинтригован... (FWIW, я работаю в Windows XP, использую R-devel, так что похоже, что это не проблема конкретной ОС или версии.)   -  person Josh O'Brien    schedule 08.06.2012
comment
@joran Я добавил вывод sessionInfo() в качестве редактирования своего вопроса.   -  person eipi10    schedule 08.06.2012
comment
Аналогичное поведение можно получить с большинством объектов ggplot2, запустив str с загрузкой library(proto) и без нее. Использование proto значительно расширяет отображение proto объектов.   -  person Faheem Mitha    schedule 19.05.2013
comment
Я считаю, что это также незначительно относится к проблеме: stackoverflow.com/a/20335767/911945 . Короче говоря, reorder нужно, чтобы второй параметр был as.factor(.) для правильного заказа.   -  person Anton Tarasenko    schedule 03.12.2013


Ответы (1)


Это происходит потому, что:

  1. gmodels импортирует gdata
  2. gdata создает новый метод для reorder.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
person Andrie    schedule 07.06.2012
comment
Вы можете получить ожидаемый порядок, используя версию gdata::reorder.factor, добавив аргумент FUN=identity: data1 = transform(data, group=reorder(group,-num,FUN=identity)). - person Brian Diggs; 08.06.2012
comment
Просто чтобы убедиться, что я понял урок: когда вы загружаете пакет, вы можете получить другое поведение с точно таким же кодом, даже при отсутствии маскировки, если новый пакет имеет метод, специфичный для вашего объекта (в данном случае reorder.factor ), который переопределяет поведение метода верхнего уровня (в данном случае универсального reorder), который в противном случае применялся бы к вашему объекту. Это правильно? - person eipi10; 08.06.2012
comment
@eipi10 eipi10 Да, ваш пример ясно иллюстрирует это. Педантизм в отношении терминологии: reorder.factor отправляется, а не reorder.default (таким образом, в некотором смысле переопределяя предыдущее поведение). Это очень интересная проблема. Спасибо. - person Andrie; 08.06.2012
comment
Андрей, спасибо за четкий и подробный ответ. @BrianDiggs Спасибо, что показали, как восстановить желаемое поведение. - person eipi10; 08.06.2012
comment
Большое спасибо всем. Эта проблема сводила меня с ума. Есть ли способ добавить еще несколько метаданных к этому вопросу, чтобы его было легче обнаружить? По крайней мере, еще одна бедняга находится в замешательстве : - person David Lovell; 01.10.2013