У меня есть набор данных под названием data_words, который выглядит следующим образом (это всего несколько строк):
Word Cognate TestingMoment Score freq
1 aambeeld Cognate Main2 0.3500000 10
2 aambeeld Cognate Main4 0.7670000 10
3 bezem Cognate Main2 1.0000000 5
4 bezem Cognate Main4 1.0000000 5
5 broodrooster Non-cognate Main2 0.5428571 14
6 broodrooster Non-cognate Main4 0.5714286 14
7 buis Non-cognate Main2 0.4545455 11
8 buis Non-cognate Main4 0.6363636 11
Я создаю его штриховой график, который пока выглядит следующим образом:

Это код, который сгенерировал сюжет:
ggplot(data_words %>% group_by(Word, Cognate) %>% arrange(desc(Score)),
aes(x = reorder(Word, -Score),
y = Score * 100,
fill = Cognate)) +
geom_bar(aes(group = TestingMoment,
colour = TestingMoment),
stat = "identity",
position = "identity",
alpha = 0.5) +
geom_text(aes(label = freq),
size = 3,
position = position_nudge(x=0.1, y=3),
data = filter(data_words, TestingMoment == "Main4")) +
theme(axis.text.x = element_text(size = 13),
axis.text.y = element_text(size = 10),
text = element_text(size = 15)) +
labs(x = "Word\n", y = "\nAverage score at Main2 and Main4") +
scale_fill_manual(values=c("#000000", "#56B4E9")) +
scale_colour_manual(values=c("white", "white"), guide=FALSE) +
coord_flip()
Есть две вещи, с которыми я борюсь и пока не могу решить, хотя я смотрел на другие вопросы по этой теме.
1) Полосы в настоящее время упорядочены по среднему значению Score по Main2 и Main4. Это делает график довольно запутанным. Как я могу отсортировать его по значению в Main2 ИЛИ Main4?
2) После выполнения пункта 1 я хочу, чтобы записи с одинаковым количеством баллов были отсортированы в алфавитном порядке. Фрейм данных уже отсортирован по алфавиту, но поскольку я переворачиваю координаты в самом конце, порядок слов прямо противоположен тому, как я хочу их. Как я могу это сделать?
Вот все данные:
structure(list(Word = structure(c(1L, 1L, 2L, 2L, 4L, 4L, 5L,
5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 11L, 11L, 12L, 12L, 13L,
13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L, 17L, 19L, 19L, 20L, 20L,
21L, 21L, 22L, 22L, 23L, 23L, 24L, 24L, 25L, 25L, 26L, 26L, 27L,
27L, 28L, 28L, 29L, 29L, 30L, 30L, 31L, 31L, 32L, 32L, 35L, 35L,
36L, 36L, 37L, 37L, 38L, 38L, 40L, 40L, 41L, 41L, 42L, 42L, 43L,
43L, 44L, 44L, 45L, 45L, 46L, 46L, 47L, 47L, 48L, 48L, 49L, 49L,
50L, 50L, 51L, 51L, 52L, 52L, 53L, 53L, 54L, 54L, 55L, 55L, 56L,
56L, 57L, 57L, 58L, 58L, 59L, 59L, 60L, 60L, 61L, 61L, 62L, 62L,
63L, 63L, 64L, 64L, 65L, 65L, 66L, 66L, 67L, 67L, 68L, 68L, 69L,
69L, 70L, 70L, 71L, 71L, 73L, 73L, 74L, 74L, 75L, 75L, 76L, 76L,
77L, 77L, 78L, 78L, 79L, 79L, 80L, 80L, 81L, 81L, 82L, 82L, 83L,
83L), .Label = c("aambeeld", "bezem", "brandblusser", "broodrooster",
"buis", "citruspers", "dienblad", "dobber", "dweil", "emmer",
"garde", "gesp", "gieter", "gum", "heggenschaar", "hengel", "hes",
"kaars", "kapstok", "keppel", "kist", "klapper", "klos", "knikker",
"knuffel", "kooi", "kous", "kraag", "kroon", "kruiwagen", "kruk",
"kurk", "kussen", "kwast", "lantaarn", "lessenaar", "mijter",
"onderzetter", "pak", "passer", "peddel", "pet", "pruik", "puntenslijper",
"rammelaar", "reddingsvest", "rietje", "rits", "romper", "sambabal",
"schort", "schroef", "servet", "skelter", "slab", "slang", "slinger",
"speen", "speldje", "spijker", "spuit", "staf", "stamper", "stelt",
"stofzuiger", "stokpaard", "stolp", "tamboerijn", "tol", "tooi",
"toverstaf", "tuinbroek", "tulband", "vergiet", "veter", "vijl",
"vijzel", "waaier", "wafelijzer", "wip", "zaag", "zeis", "zwemvleugel"
), class = "factor"), Cognate = structure(c(1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L,
1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L,
2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 1L,
1L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L,
2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L), .Label = c("Cognate", "Non-cognate"), class = "factor"),
TestingMoment = structure(c(2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L,
3L, 2L, 3L, 2L, 3L, 2L, 2L, 3L, 2L, 3L, 3L, 2L, 3L, 2L, 2L,
3L, 2L, 3L, 3L, 2L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 3L, 2L, 3L,
2L, 3L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 2L,
3L, 2L, 3L, 2L, 3L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 3L, 3L, 2L,
2L, 3L, 3L, 2L, 3L, 2L, 2L, 3L, 2L, 3L, 3L, 2L, 3L, 2L, 2L,
3L, 3L, 2L, 2L, 3L, 2L, 3L, 3L, 2L, 3L, 2L, 2L, 3L, 3L, 2L,
3L, 2L, 3L, 2L, 3L, 2L, 2L, 3L, 2L, 3L, 3L, 2L, 2L, 3L, 2L,
3L, 3L, 2L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 3L, 2L, 3L, 2L, 3L,
3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 2L, 3L, 2L, 3L, 2L, 3L, 2L,
3L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L), .Label = c("Post", "Main2",
"Main4", "FollowUp"), class = "factor"), Score = c(0.35,
0.767, 1, 1, 0.542857142857143, 0.571428571428571, 0.454545454545455,
0.636363636363636, 1, 1, 1, 1, 0.866666666666667, 0.666666666666667,
1, 1, 0.042, 0.108666666666667, 0.383333333333333, 0.25,
0.871538461538462, 0.512307692307692, 0.9175, 1, 1, 1, 0.946666666666667,
0.493333333333333, 0.585, 0.5, 0.362307692307692, 0.692307692307692,
0.5, 0.416666666666667, 0.003, 1, 1, 1, 0.35, 0.616666666666667,
1, 1, 1, 1, 0.785714285714286, 0.714285714285714, 0.227272727272727,
0.181818181818182, 1, 0.9, 1, 1, 0.504666666666667, 0.908,
0.9375, 1, 0.666666666666667, 0.944444444444444, 0.75, 0.6425,
0.686, 0.871333333333333, 0.335, 0.335, 1, 1, 0.666666666666667,
0.6, 0.571428571428571, 0.857142857142857, 1, 1, 0.7, 0.6375,
0.648666666666667, 0.678666666666667, 0.71, 1, 0.9, 0.8,
0.75, 0.583333333333333, 1, 1, 0.83, 0.003, 0.902666666666667,
0.917333333333333, 0.261538461538462, 0.384615384615385,
0.42, 0.353, 0.93, 0.9475, 0.214285714285714, 0.612142857142857,
0.533333333333333, 0.316666666666667, 1, 0.833333333333333,
0.857142857142857, 0.785714285714286, 0.732142857142857,
0.357142857142857, 0.285714285714286, 0.857142857142857,
0.559285714285714, 0.785714285714286, 0.25, 0.25, 0.75, 1,
0.903333333333333, 1, 0.573571428571429, 0.532857142857143,
1, 1, 1, 1, 0.25, 0.003, 0.916666666666667, 1, 0.316666666666667,
0.533333333333333, 0.714285714285714, 0.857142857142857,
0.7225, 0.695, 0.593333333333333, 0.279333333333333, 1, 1,
0.230769230769231, 0.153846153846154, 0.003, 0.003, 0.269285714285714,
0.342857142857143, 0.666666666666667, 0.866666666666667,
0.698571428571429, 0.841428571428571, 1, 0.916666666666667,
0.757272727272727, 0.533636363636364, 0.555833333333333,
0.479166666666667, 0.99, 0.99), freq = c(10L, 10L, 5L, 5L,
14L, 14L, 11L, 11L, 3L, 3L, 1L, 1L, 3L, 3L, 1L, 1L, 15L,
15L, 15L, 15L, 13L, 13L, 4L, 4L, 1L, 1L, 15L, 15L, 4L, 4L,
13L, 13L, 6L, 6L, 1L, 1L, 2L, 2L, 15L, 15L, 1L, 1L, 11L,
11L, 14L, 14L, 11L, 11L, 10L, 10L, 1L, 1L, 15L, 15L, 4L,
4L, 9L, 9L, 12L, 12L, 15L, 15L, 2L, 2L, 11L, 11L, 15L, 15L,
7L, 7L, 1L, 1L, 8L, 8L, 15L, 15L, 1L, 1L, 1L, 1L, 12L, 12L,
10L, 10L, 1L, 1L, 15L, 15L, 13L, 13L, 10L, 10L, 8L, 8L, 14L,
14L, 15L, 15L, 12L, 12L, 14L, 14L, 14L, 14L, 7L, 7L, 14L,
14L, 3L, 3L, 4L, 4L, 3L, 3L, 14L, 14L, 1L, 1L, 8L, 8L, 4L,
4L, 12L, 12L, 15L, 15L, 7L, 7L, 4L, 4L, 15L, 15L, 1L, 1L,
13L, 13L, 1L, 1L, 14L, 14L, 15L, 15L, 7L, 7L, 12L, 12L, 11L,
11L, 12L, 12L, 10L, 10L)), .Names = c("Word", "Cognate",
"TestingMoment", "Score", "freq"), row.names = c(NA, -152L), class = "data.frame")
Это суть сообщения: «Моя проблема в том, что данные на моем графике отсортированы по среднему значению двух уровней TestingMoment, тогда как я хочу, чтобы они были отсортированы по значению одного из уровней». Это не рассматривается в «повторяющемся» вопросе.
Небольшой момент по закрытию / дублированию: мы получаем много-много вопросов по SO, которые представлены как «как мне изменить порядок столбцов в этом ggplot?». Ответ самый общий: всегда переупорядочивает уровни факторов. Это не всегда помогает, если вопрос настоящий оказывается «как мне изменить порядок уровней в этом конкретном случае?». Так что было бы полезно, если бы (1) люди здесь были немного более открыты для этой проблемы и (2) когда вы писали свой вопрос, более пристально сосредотачивались на просто, части переупорядочения, которая не требовала бы всего постороннего кода ggplot2.
Спасибо - отметили!





Попробуй это:
library(dplyr)
Main2_order <- data_words %>%
filter(TestingMoment == 'Main2') %>%
arrange(Score,Word) %>%
pull(Word) %>%
as.character()
Main4_order <- data_words %>%
filter(TestingMoment == 'Main4') %>%
arrange(Score,Word) %>%
pull(Word) %>%
as.character()
data_words %>%
group_by(Word, Cognate) %>%
arrange(desc(Score)) %>%
ggplot(data = .,
aes(x = factor(Word,levels = rev(Main2_order)),
y = Score * 100,
fill = Cognate)) +
geom_bar(aes(group = TestingMoment,
colour = TestingMoment),
stat = "identity",
position = "identity",
alpha = 0.5) +
geom_text(aes(label = freq),
size = 3,
position = position_nudge(x=0.1, y=3),
data = filter(data_words, TestingMoment == "Main4")) +
theme(axis.text.x = element_text(size = 13),
axis.text.y = element_text(size = 10),
text = element_text(size = 15)) +
labs(x = "Word\n", y = "\nAverage score at Main2 and Main4") +
scale_fill_manual(values=c("#000000", "#56B4E9")) +
scale_colour_manual(values=c("white", "white"), guide=FALSE) +
coord_flip()
Я только вставил Main2_order в код ggplot в этом примере, но вы можете заменить другой для другого порядка.
Чтобы получить более сложный порядок с помощью Main4, затем Main2, затем Word, вы можете попробовать:
library(tidyr)
Main2_Main4_order <- data_words %>%
select(Word,TestingMoment,Score) %>%
spread(key = TestingMoment,value = Score) %>%
arrange(Main4,Main2,Word) %>%
pull(Word) %>%
as.character()
Большое спасибо, этот код делает то, о чем я просил. Если у вас есть время, у меня есть еще один вопрос. Можно ли сначала отсортировать по Main4_order, ЗАТЕМ по Main2_order и только потом по алфавиту?
Отлично, спасибо вам большое! Это именно то, что мне нужно для моей исследовательской статьи :)