Как создать подмножество с ggplot, основанным на фасетных агрегатах? - PullRequest
0 голосов
/ 24 мая 2018

У меня есть набор данных с 16 группами, доступными для фасетов, однако это слишком много, и я хотел бы сохранить только самые важные группы (определяемые тем, какой процент определенного общего числа попадает в эту группу).Например, я хотел бы сохранить только группы, которые представляют 30% или более от общего числа Var1.

Для иллюстрации, если я запускаю следующий код, R правильно выводит два вида, чья сумма Petal.length представляет более 30% от общей длины Petal.length в наборе данных (игнорируйте, что это бессмысленная статистика в этомcase).

library(tidyverse)

iris %>% 
  group_by(Species) %>% 
  summarise(t_length = sum(Petal.Length),
            p_length = round(100*t_length/sum(.$Petal.Length))) %>% 
  filter(p_length >=30)

Итак, я хотел бы получить фасет ggplot для всех групп, удовлетворяющих указанному условию.В моем наборе данных только 5 из 16 групп фиксируют более 90% интересных наблюдений, поэтому мне не нужны остальные 11 групп в сетке фасетов.

Это моя попытка, и результатэто все 3 вида, где должны быть только те же 2 из таблицы выше:

iris.sub <- ggplot(subset(iris, round(100*sum(Petal.Length)/sum(iris$Petal.Length)) >= 30), aes(x = ' ', y = Petal.Length)) +
  geom_point(stat = 'summary', fun.y = 'mean') +
  geom_errorbar(stat = 'summary', fun.data = 'mean_se', 
                width=0, fun.args = list(mult = 1.96)) +
  facet_grid( . ~ Species ) +
  theme_bw()
iris.sub

1 Ответ

0 голосов
/ 26 мая 2018

filter не будет зависеть от group_by.Например, если у вас есть фрейм данных, сгруппированный по столбцу var1, и вы хотите отфильтровать строки с столбцом x> 50, тот факт, что наблюдение находится в определенной группе, не влияет на тот факт, чточисло равно или не больше 50.

Вот два способа сделать это с некоторыми dplyr функциями.Первое вычисляет долю, которую каждая группа вносит в общую длину лепестка, вытаскивает эти виды и сохраняет ее как вектор.Затем вы фильтруете фрейм данных только для наблюдений с одним из этих видов и строите график.

Второй выполняет эти вычисления и выводит все в один блок.Преимущество этого в том, что вам не нужно сохранять переменную для вида, который вы держите;недостатком является то, что выполнение математических расчетов в mutate вызовах, а не summarise, является грязным и может привести к ошибкам, если вы не будете осторожны с тем, что именно вам нужно сложить (говоря это из опыта).

library(tidyverse)

major_categories <- iris %>%
  group_by(Species) %>%
  summarise(group_Petal.Length = sum(Petal.Length)) %>%
  mutate(share_Petal.Length = group_Petal.Length / sum(group_Petal.Length)) %>%
  filter(share_Petal.Length >= 0.3) %>%
  pull(Species)

iris %>%
  filter(Species %in% major_categories) %>%
  ggplot(aes(x = 1, y = Petal.Length)) +
    geom_point(stat = "summary", fun.y = "mean") +
    geom_errorbar(stat = "summary", fun.data = "mean_se", width = 0, fun.args = list(mult = 1.96)) +
    facet_grid(. ~ Species) +
    theme_bw()

iris %>%
  group_by(Species) %>%
  mutate(group_Petal.Length = sum(Petal.Length)) %>%
  ungroup() %>%
  mutate(share_Petal.Length = group_Petal.Length / sum(unique(group_Petal.Length))) %>%
  filter(share_Petal.Length >= 0.3) %>%
  ggplot(aes(x = 1, y = Petal.Length)) +
    geom_point(stat = "summary", fun.y = "mean") +
    geom_errorbar(stat = "summary", fun.data = "mean_se", width = 0, fun.args = list(mult = 1.96)) +
    facet_grid(. ~ Species) +
    theme_bw()

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

...