Как создать расширенную стратификацию ggplot по переменной? - PullRequest
0 голосов
/ 04 августа 2020

У меня есть фрейм данных в R с несколькими разными столбцами, например, этот

library(ggplot2)
a <- data.frame(
    "order" = c("A", "A", "A", "B", "B", "B", "C","C","D"), 
    "family" = c("A_1", "A_2", "A_3", "B_1", "B_2", "B_3", "C_1","C_2","D_1"), 
    "counts"=c(10,23,51,21,89,32,58,9,67)
)
a

Я хочу сделать столбчатую диаграмму подсчетов для каждой семьи внутри по порядку. Я знаю, что это звучит запутанно, но в порядке A есть семейства A_1, A_2 и A_3, в порядке B есть семейства B_1, B_2, B_3 и так далее ... Каждая из этих семей в порядке имеет определенное количество c, которое является столбец «подсчитывает». Я пробовал эту простую команду:

ggplot(a, aes(x=family, y=counts)) + geom_bar()

, но она не расслаивается по порядку и не представляет каждую семью внутри и по порядку. Как мне добиться этого расслоения и чтобы все семейства в пределах заказов отображались на одной странице графика в R?

1 Ответ

0 голосов
/ 04 августа 2020

Сначала несколько терминов. Под «расслоением» искомый термин называется «группировка»: вы хотите отобразить один столбец с количеством счетчиков на a$family и сгруппировать эти столбцы по a$order. К счастью, этот кажущийся «продвинутый» сюжет довольно легко создать, если вы немного разберетесь с терминологией и использованием в ggplot2. Я проведу вас через процесс, чтобы он был понятен.

Во-первых, основной график c. Вы используете geom_bar(), но здесь вы должны использовать geom_col(). Вы можете прочитать о причине почему в документации , но достаточно сказать, что если вы указываете только x aestheti c, вы используете geom_bar(). Если вы указываете эстетику x и y, вы используете geom_col().

Для части grouping у вас есть два основных варианта: (1) использовать группировку и уклонение, или (2) использовать огранку. Оба работают нормально, и, честно говоря, это зависит от того, как вы хотите, чтобы результат выглядел. Я покажу и то, и другое.

Группировка и уклонение

Группировка довольно ясна. «Уклонение» означает, что ggplot берет ваши группы и разделяет их, изменяя способ их отображения вдоль оси x. Подход состоит в использовании a$order в качестве оси x и a$family для группировки. Если мы просто построим это, вы получите график ниже:

ggplot(a, aes(x=order, y=counts)) + geom_col(color='black', alpha=0.2)

enter image description here

I've added an alpha= value and colored the outline of the bars black so that we can see what's going on here: all the bars for a$family are plotting on top of one another, since multiple a$family bars share the same a$order value. Your bars are therefore "grouped", but they are not separated out so we can see them. Doing this is what is known as "dodging": separating placement of geoms that share the same x value to avoid overplotting. We handle that placement using position=. The problem is that ggplot2 still needs to be told on what column you want to perform the groups. For that, you need the group= aesthetic:

ggplot(a, aes(x=order, y=counts, group=family)) +
  geom_col(
    position='dodge',
    color='black', alpha=0.2)

enter image description here

Looks great, but you need to control a few things here. We need some way to identify the bars and also need to control the relative widths of each bar... we would like them to be the same size. That bar to the right is wider than all the rest and is ugly.

To fix the bar widths, you can use position=position_dodge2(preserve='single'). Using position_dodge2() is important here, because the related position_dodge() would work, but not center along each x axis position.

To add labels, I'll use geom_text(). Note a few things we do though, which is to "nudge" the values up a bit by adding some value to the y= aesthetic. I also need to use the same position= argument we used for the bars to apply to the text so that it dodges the same amount.

p 

enter image description here

By the way, another good way to identify the families would be to use a different fill= aesthetic applied to a$family. I'm not going to show you that here though, since I would recommend doing a few other things with your data first (not for this question!).
Finally, we can make your vertical bars horizontal by adding coord_flip() to our plot (which switches the axes):

p + coord_flip()

enter image description here

Faceting

The other way to group is to use facets. In this case, you plot a$family as the x axis and then "separate" your groups using facet_wrap() or facet_grid(). Here, I'll use facet_grid().

ggplot(a, aes(x=family, y=counts)) +
  geom_col(color='black', alpha=0.2) +
  coord_flip() +
  facet_grid(order ~ ., scales = 'free', space='free')

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

Нам здесь не нужен какой-либо механизм маркировки, но я предпочитаю использовать здесь facet_grid для конкретной c причины, по которой мы можем использовать аргумент space=, что не является присутствует в facet_wrap(). Без этого аргумента фасеты были бы равны по размеру, и результат очень похож на то, что мы имели в Группировании и Уклонении до использования position_dodge2(preserve='single'). Аргумент scales= необходим, потому что в противном случае у вас будут пробелы в каждом фасете для каждого a$family - даже если ничего не существует.

Если вы хотите испортить размещение меток фасетов, вы используете switch= внутри facet_grid() (как узнать в документации). Чтобы изменить внешний вид этих ярлыков, вы используете theme() элементы strip.*.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...