Как запретить R ранжировать данные в алфавитном порядке в ggplot и указать порядок, в котором данные отображаются (данные + код + графики)?

Я пытаюсь исправить проблему с моим графиком GGBalloonPlot в отношении того, как R обрабатывает метки осей.

По умолчанию R отображает данные, используя метки, ранжированные в обратном алфавитном порядке, но чтобы выявить закономерность данных, данные необходимо отображать в определенном порядке. Единственный способ обмануть программное обеспечение — вручную добавить префикс к каждой метке в моей таблице .csv, чтобы R правильно ранжировал их в моем выводе. Это отнимает много времени, так как мне нужно вручную упорядочить данные, прежде чем добавлять префикс, а затем строить графики.

Я хотел бы ввести вектор символов (или что-то в этом роде), который, по сути, указывал бы порядок, в котором я хочу отображать данные, которые будут отображать шаблон без необходимости префикса в имени метки.

Я предпринял несколько попыток с "scale_y_discrete" безуспешно. Я также хотел бы сделать то же самое для оси X, поскольку мне пришлось использовать тот же «трюк» для отображения столбцов в правильном неалфавитном порядке, который смещает положение меток. Любая идея о том, как заставить GGplot отображать мои значения, как показано на графике, без необходимости «обманывать» программное обеспечение, поскольку это занимает довольно много времени?

Данные + код

#Assign data to "Stack_Overflow_DummyData"

Stack_Overflow_DummyData <- structure(list(Species = structure(c(8L, 3L, 1L, 5L, 6L, 2L, 
                                     7L, 4L, 8L, 3L, 1L, 5L, 6L, 2L, 7L, 4L, 8L, 3L, 1L, 5L, 6L, 2L, 
                                     7L, 4L, 8L, 3L, 1L, 5L, 6L, 2L, 7L, 4L), .Label = c("Ani", "Cal", 
                                                                                         "Can", "Cau", "Fis", "Ort", "Sem", "Zan"), class = "factor"), 
               Species_prefix = structure(c(8L, 7L, 6L, 5L, 4L, 3L, 2L, 
                                            1L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L, 8L, 7L, 6L, 5L, 4L, 3L, 
                                            2L, 1L, 8L, 7L, 6L, 5L, 4L, 3L, 2L, 1L), .Label = c("ac.Cau", 
                                                                                                "ad.Sem", "af.Cal", "ag.Ort", "as.Fis", "at.Ani", "be.Can", 
                                                                                                "bf.Zan"), class = "factor"), Dist = structure(c(2L, 3L, 
                                                                                                                                                 5L, 2L, 1L, 1L, 4L, 5L, 2L, 3L, 5L, 2L, 1L, 1L, 4L, 5L, 2L, 
                                                                                                                                                 3L, 5L, 2L, 1L, 1L, 4L, 5L, 2L, 3L, 5L, 2L, 1L, 1L, 4L, 5L
                                                                                                ), .Label = c("End", "Ind", "Pan", "Per", "Wid"), class = "factor"), 
               Region = structure(c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 
                                    4L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Cen", "Col", 
                                                                                "Far", "Nor"), class = "factor"), Region_prefix = structure(c(1L, 
                                                                                                                                              1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                                                                                                                              3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
                                                                                                                                              4L), .Label = c("a.Far", "b.Nor", "c.Cen", "d.Col"), class = "factor"), 
               Frequency = c(75, 50, 25, 50, 0, 0, 0, 0, 11.1, 22.2, 55.6, 
                             55.6, 11.1, 0, 5.6, 0, 0, 2.7, 36.9, 27.9, 65.8, 54.1, 37.8, 
                             28.8, 0, 0, 0, 3.1, 34.4, 21.9, 78.1, 81.3)), class = "data.frame", row.names = c(NA, 
                                                                                                               -32L))



# Plot Data With Prefix Trick

library(ggplot2)
library(ggpubr)

# make color base on Dist, size and alpha dependent on Frequency
ggballoonplot(Stack_Overflow_DummyData, x = "Region_prefix", y = "Species_prefix", 
              size = "Frequency", size.range = c(1, 9), fill = "Dist") +
  theme_set(theme_gray() + 
  theme(legend.key=element_blank())) + 
  # Sets Grey Theme and removes grey background from legend panel
  theme(axis.title = element_blank()) +
  # Removes X axis title (Region)
  geom_text(aes(label=Frequency), alpha=1.0, size=3, nudge_x = 0.4) 
# Add Frequency Values Next to the circles

# Plot Data Without Prefix Trick

library(ggplot2)
library(ggpubr)

# make color base on Dist, size and alpha dependent on Frequency
ggballoonplot(Stack_Overflow_DummyData, x = "Region", y = "Species", 
              size = "Frequency", size.range = c(1, 9), fill = "Dist") +
  theme_set(theme_gray() + 
  theme(legend.key=element_blank())) + 
  # Sets Grey Theme and removes grey background from legend panel
  theme(axis.title = element_blank()) +
  # Removes X axis title (Region)
  geom_text(aes(label=Frequency), alpha=1.0, size=3, nudge_x = 0.4) 
# Add Frequency Values Next to the circles

Вот ниже графики

Хороший график.

Использование трюка с префиксом метки с видимым шаблоном в данных:

введите здесь описание изображения

Неправильный график (R по умолчанию).

Без трюка с префиксом, когда GGplot автоматически упорядочивает данные/метки, а график не имеет смысла:

введите здесь описание изображения

Подводя итог, я хотел бы, чтобы график Good выводился без необходимости предварительно добавлять префикс в мои метки.

Большое спасибо заранее за вашу помощь.


person Etienne    schedule 12.06.2020    source источник
comment
Привет, Этьен, добро пожаловать в SO. Сожалеем, что хороший вопрос вызвал у вас головную боль. Просто многие люди предлагают помощь бесплатно, и самое меньшее, что мы можем ожидать, это то, что «помощник» пойдет навстречу помощникам. Я вижу, ты все собрал. Спасибо за это. Еще две вещи: если у вас возникли проблемы с форматированием кода, есть функция справки, которая подскажет, как это сделать. Тогда это обычно работает для меня. И, пожалуйста, задавайте по 1 вопросу за раз. Поэтому, пожалуйста, разделите свой вопрос. Причина в том, что мы хотим, чтобы каждый получил пользу от ответов, а смешанные вопросы затрудняют это.   -  person Jan    schedule 12.06.2020
comment
Код в ссылке представляет собой файл docx. Скопируйте его содержимое и вставьте в текстовый редактор. Избавьтесь от умных кавычек, если они есть. Затем нужно скопировать код в поле редактирования SO. Чтобы отформатировать его как код, поставьте 3 обратных кавычки до и после блока кода или сделайте отступ в 4 пробела в каждой строке.   -  person Rui Barradas    schedule 12.06.2020
comment
Основная цель Stack Overflow — предоставить вопросы и ответы для будущих пользователей с такими же проблемами. Это еще одна веская причина, по которой вопросы должны быть минимальными, воспроизводимыми и автономными. Если ваш вопрос зависит от кода и данных в вашем личном дропбоксе, вопрос начинается как менее доступный — никто не может сразу увидеть вашу попытку или ваши данные. И если эти ссылки когда-либо устареют, вся воспроизводимость будет потеряна. Мы хотим помочь вам, но мы хотим помочь большему количеству людей, чем только вам. Поэтому мы хотим, чтобы вы задали свой вопрос таким образом, чтобы помочь большему количеству людей.   -  person Gregor Thomas    schedule 12.06.2020
comment
В связи с этим я бы посоветовал вам поделиться минимальным воспроизводимым примером. Нам не нужны все ваши данные для настройки надписей и легенд — достаточно нескольких строк. Совместного использования данных по 3 или 4 видам, вероятно, достаточно.   -  person Gregor Thomas    schedule 12.06.2020
comment
Спасибо за все ваши отзывы и за редактирование поста. Я изменил пост в соответствии с вашими комментариями, а именно: - Сделав его одним единственным вопросом. - Совместное использование минимального воспроизводимого примера, который не зависит от ссылки DropBox, чтобы вопрос был полезен другим в будущем.   -  person Etienne    schedule 17.06.2020


Ответы (1)


Для меток осей я бы определил предыдущую функцию для переопределения разрывов:

shlab <- function(lbl_brk){
  sub("^[a-z]+\\.","",lbl_brk) # removes the starts of strings as a. or ab.
}

Затем, чтобы изменить метки, вам просто нужно использовать scale_x,y_discrete с labels = shlab (если вы посмотрите на справку scale_x_discrete, вы увидите, что одним из вариантов для labels является A function that takes the breaks as input and returns labels as output).

Для цветов достаточно было бы поменять их (values) на scale_fill_manual а для размеров, используя guides так:

library(ggplot2)
library(ggpubr)
shlab <- function(lbl_brk){
  sub("^[a-z]+\\.","",lbl_brk)
}
ggballoonplot(Stack_Overflow_DummyData, x = "Region_prefix", y = "Species_prefix", size = "Frequency", size.range = c(1, 9), fill = "Dist") +
  scale_x_discrete(labels = shlab) +
  scale_y_discrete(labels = shlab) +
  scale_fill_manual(values = c("green", "blue", "red", "black", "white")) +
  guides(fill = guide_legend(override.aes = list(size=8))) +
  theme_set(theme_gray() + theme(legend.key=element_blank())) +     # Sets Grey Theme and removes grey background from legend panel
  theme(axis.title = element_blank()) +                             # Removes X axis title (Region)
  geom_text(aes(label=Frequency), alpha=1.0, size=3, nudge_x = 0.4) # Add Frequency Values Next to the circles

введите здесь описание изображения

ОБНОВЛЕНИЕ:

С новым набором данных и векторными метками:

library(ggplot2)
library(ggpubr)

# make color base on Dist, size and alpha dependent on Frequency
ggballoonplot(Stack_Overflow_DummyData, x = "Region", y = "Species", 
              size = "Frequency", size.range = c(1, 9), fill = "Dist") +
  scale_y_discrete(limits = c("Cau", "Sem", "Cal", "Ort", "Fis", "Ani", "Can", "Zan")) +
  scale_x_discrete(limits = c("Far", "Nor", "Cen", "Col")) +
  theme_set(theme_gray() + 
              theme(legend.key=element_blank())) + 
  # Sets Grey Theme and removes grey background from legend panel
  theme(axis.title = element_blank()) +
  # Removes X axis title (Region)
  geom_text(aes(label=Frequency), alpha=1.0, size=3, nudge_x = 0.4) 

введите здесь описание изображения

person iago    schedule 12.06.2020
comment
Это здорово, чтобы удалить префикс и изменить легенду! Однако это не решает проблему необходимости префикса в первую очередь, чтобы сюжет получился таким. Я хотел бы получить такой же вывод без необходимости использования префикса, просто предоставив желаемый порядок меток в виде вектора символов (или аналогичного). - person Etienne; 17.06.2020
comment
Вы можете посмотреть здесь: stackoverflow .com/questions/3253641/ - person iago; 17.06.2020
comment
Просто добавляю: scale_y_discrete(limits = c("Cau", "Sem", "Cal", "Ort", "Fis", "Ani", "Can", "Zan")) + scale_x_discrete(limits = c("Far", "Nor", "Cen", "Col")) + - person iago; 17.06.2020
comment
Потрясающий ! Это именно то, чего я пытаюсь достичь! Вероятно, я просто неправильно использовал эту функцию, когда впервые попробовал ее. Большое спасибо. - person Etienne; 19.06.2020