Гистограммы с множественными группировками факторов и средними значениями переменной по этим факторам

Я пытаюсь создать диаграмму, которая показывает среднюю почасовую заработную плату профсоюзов и работников, не состоящих в профсоюзах, сгруппированных по одиноким или состоящим в браке, сгруппированных по выпускникам колледжа или не выпускникам колледжа. Хотя мне удалось построить удовлетворительную гистограмму с двумя группировками факторов, я не могу понять, как это сделать с группировками по трем факторам. Примеры, которые я видел, в которых есть три фактора, смотрят только на подсчет частоты, поэтому я не уверен, как включить в график среднее значение другой переменной по всем факторам. Я хочу создать что-то похожее на это (создано в Stata): Средняя почасовая оплата по Статус союза, семейное положение и окончание колледжа Мой код выглядит так:

levelbar = tapply(wage, list(as.factor(union), as.factor(married), 
as.factor(collgrad)), mean)
par(mfrow = c(1, 2))
barplot(levelbar, beside = TRUE)
barplot(t(levelbar), beside = TRUE)

Однако когда я запускаю это, я получаю сообщение об ошибке:

Error in barplot.default(levelbar, beside = TRUE) : 
'height' must be a vector or a matrix

Любая помощь по этому поводу будет оценена. Я уверен, что ggplot может быть здесь полезен, но у меня нет большого опыта использования этого пакета.


person Christian Conroy    schedule 08.10.2017    source источник


Ответы (1)


Вот воспроизводимый пример с использованием ggplot и встроенного набора данных Titanic.

Обратите внимание, что мы сначала вычисляем средние и используем stat = identity, чтобы убедиться, что мы включили их в график.

# Format the Titanic dataframe
Titanic_df <- Titanic %>% as_tibble()

# Make Class, Sex, Age, and Survived factors
for (col in c("Class", "Sex", "Age", "Survived")) {
  Titanic_df[[col]] <- factor(Titanic_df[[col]])
}

# Get by group means
means <- Titanic_df %>% 
  group_by(Class, Sex, Survived) %>% 
  summarise(
    mean_n = mean(n)
  )

# Plot: facets are the Classes, bar colors are the two Sexes, and the groupings in each facet are Survived vs. Not Survived
ggplot(data = means) +
  geom_bar(aes(x = Survived, y = mean_n, fill = Sex), stat = "identity", position = "dodge") +
  facet_wrap(~ Class)

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

person amanda    schedule 08.10.2017
comment
Спасибо! Если я хочу исключить третий столбец, который появляется на уровне коэффициента объединения b / c, где есть NA, где я бы это поместил? Я пробовал means <- nlsw_df %>% na.omit() %>% group_by(union, married, collgrad) %>% summarise( mean_wage = mean(wage) ) пробовал ggplot(data = na.omit(means)) + geom_bar(aes(x = collgrad, y = mean_wage, fill = union), stat = "identity", position = "dodge") + facet_wrap(~ married) пробовал for (col in c("union", "married", "collgrad")) { nlsw_df[[col]] <- factor(nlsw_df[[col]], exclude = NA) } - person Christian Conroy; 08.10.2017
comment
Похоже, что есть еще уровень фактора NA, хотя вы избавились от значений NA. Связывание droplevels() после того, как вы na.omit() (или drop_na(union), если вы хотите выбросить только строки с NA в столбце объединения), должно помочь. - person amanda; 08.10.2017
comment
Привет, Аманда, спасибо за ответ. Я думаю, вы правы, говоря, что это правильно, но я не могу заставить его работать по какой-то причине. Несмотря на цепочку dropvels () после na.omit (), третья неиспользуемая полоса NA все еще отображается на графике. Я запустил следующий код: means <- nlsw_df %>% na.omit(union) %>% droplevels(union) %>% group_by(union, married, collgrad) %>% summarise( mean_wage = mean(wage) ) ggplot(data = means) + geom_bar(aes(x = collgrad, y = mean_wage, fill = union), stat = "identity", position = "dodge") + facet_wrap(~ married) - person Christian Conroy; 09.10.2017
comment
Если у вас есть NA на оси x, это означает, что вы не отбрасывали NA в collgrad. Я бы использовал droplevels() для всего фрейма данных, поэтому means <- nlsw_df %>% na.omit() %>% droplevels() %>% group_by(union, married, collgrad) %>% summarise( mean_wage = mean(wage) ). Это должно привести к падению всех НП и всех уровней НП. Если это не сработает, легче понять, что происходит, если вы можете показать пример того, как выглядят данные (либо первые несколько строк, либо что-то, что хорошо имитирует). - person amanda; 10.10.2017
comment
@amanda Используя titanic и ваш код, я получаю это сообщение об ошибке Ошибка: хотя бы один слой должен содержать все переменные фасетирования: Class. * График отсутствует Class * Уровень 1 отсутствует Class Отслеживание: 1. (function (x, ...) ... 2. ggplot2 ::: print.ggplot (x) 4. ggplot2 ::: ggplot_build.ggplot (x ) 5. layout $ setup (data, plot $ data, plot $ plot_env) 6. ggplot2 ::: f (..., self = self) 7. self $ facet $ compute_layout (data, self $ facet_params) 8. ggplot2 ::: f (...) 11. ggplot2 :: comb_vars (данные, параметры $ plot_env, vars, drop = params $ drop) - person sar; 13.04.2020
comment
@sar хм у тебя means столбец Class? Похоже, Class там нет. - person amanda; 13.04.2020