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

17

Я хотел создать панель, в которой бары были упорядочены по высоте, а не по алфавиту по категориям. Это отлично работало, когда единственным загруженным мной пакетом был 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: Ran 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: Ran 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
    
задан eipi10 07.06.2012 в 22:39
источник
  • Не могли бы вы предоставить выходные данные sessionInfo ()? Если кто-то может помочь, им, возможно, придется сопоставить ваши версии R и пакета, чтобы воспроизвести это. –  joran 07.06.2012 в 22:49
  • Я могу воспроизвести это на R 2.15.0 с обновленными пакетами CRAN (на Ubuntu) –  Justin 07.06.2012 в 22:54
  • Очень интересно. Похоже, что изменение результатов transform () появляется только после загрузки gmodels (и оно не фиксируется последующим отсоединением gmodels). Я заинтригован ... (FWIW, я нахожусь в Windows XP, запустил R-devel, поэтому похоже, что это не проблема с ОС или версией). –  Josh O'Brien 07.06.2012 в 23:14
  • @joran Я добавил вывод sessionInfo () как редактирование на мой вопрос. –  eipi10 07.06.2012 в 23:14
  • Вы можете получить подобное поведение с большинством объектов ggplot2, запустив str с и без загрузки библиотеки (proto). Использование proto значительно расширяет отображение прото-объектов. –  Faheem Mitha 19.05.2013 в 16:45

1 ответ

13

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

  1. gmodels import 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
    
ответ дан Andrie 07.06.2012 в 23:36
  • Вы можете получить «ожидаемый» порядок, используя версию gdata :: reorder.factor, добавив аргумент FUN = identity: data1 = transform (data, group = reorder (group, -num, FUN = identity)). –  Brian Diggs 07.06.2012 в 23:46
  • Просто чтобы убедиться, что я понял этот урок: когда вы загружаете пакет, вы можете получить другое поведение с тем же кодом даже при отсутствии маскировки, если новый пакет имеет метод, специфичный для вашего объекта (в этот случай reorder.factor), который «переопределяет» поведение метода «верхнего» уровня (в данном случае, общий порядок), который в противном случае применим к вашему объекту. Это верно? –  eipi10 08.06.2012 в 14:34
  • @ eipi10 Да, ваш пример наглядно иллюстрирует это. Педантизм о терминологии: reorder.factor отправляется, а не reorder.default (таким образом, в некотором смысле, переопределяя предыдущее поведение). Это очень интересная проблема. Спасибо. –  Andrie 08.06.2012 в 14:44
  • Andrie, спасибо за четкий и подробный ответ. @BrianDiggs Спасибо, что продемонстрировали, как восстановить желаемое поведение. –  eipi10 08.06.2012 в 15:08
  • Большое спасибо всем. Эта проблема привела меня в бешенство. Есть ли способ добавить некоторые метаданные к этому вопросу, чтобы сделать его более легкодоступным? Там есть, по крайней мере, еще одна бедная душа в состоянии замешательства: –  David Lovell 01.10.2013 в 12:23