Как рассчитать SD по группе в R, не теряя при этом все еще необходимые столбцы для построения графика в ggplot2? - PullRequest
2 голосов
/ 30 марта 2020

У меня есть набор данных 'сценария (27x), где A, B en C были определенными входными значениями в модель, а значение является результатом переменной.

Теперь я хочу создать сгруппированный барплот с ggplot (значение на y, с фактором B на x, заполнить на A. Я хочу создавать панели ошибок на основе отклонения, вызванного фактором C.

Мой набор данных (упрощенно) приблизительно в следующем формате:

data <- data.frame(matrix(ncol=0, nrow=27))
data$value <- runif(27, min=10, max=60)
data$A <- factor((rep(1:9, each=3)))
data$B <- factor((rep(1:3, each=9)))
data$C <- factor(rep(rep(1:3),9))

Похоже:

     value A B C
1 27.76710 1 1 1
2 34.71762 1 1 2
3 20.72895 1 1 3
4 34.83710 2 1 1
5 31.44144 2 1 2
6 13.11038 2 1 3
etc

График ggplot будет

ggplot(data, aes(fill=A, y=value, x=B)) + 
  geom_bar(stat="identity",position=position_dodge())+
  geom_errorbar(aes(ymin=?????, ymax=????), width=.2,
                position=position_dodge(.9))

Так что я Я борюсь с ymin и ymax. Это может быть значение + sd или -sd, но у меня еще не вычислено sd.

Мой подход сейчас использует суммирование от dplyr по группе A. Это дает мне:

data %>% 
group_by(A) %>% 
summarise(mean=mean(value), sd = sd(value))

  A      mean    sd
  <fct> <dbl> <dbl>
1 1      27.7  6.99
2 2      26.5 11.7 
3 3      33.7 21.9 
4 4      27.7  6.99
etc

Это нормально, однако теперь я потерял все остальные мои столбцы (в этом случае мне все еще нужен B для моего ggplot). Как мне все еще вычислить среднее значение и sd и сохранить все остальные мои столбцы ?

Или есть другие способы получить нужный мне эффект? (Я мог бы заново добавить столбец B вручную, но я хотел бы знать, есть ли другие способы также для будущего и для случаев B нелегко переделать)

1 Ответ

3 голосов
/ 30 марта 2020

У вас есть три строки данных для каждой комбинации A и B, поэтому ваш текущий код фактически перекрывает три бара в каждой позиции оси x. Вы можете увидеть это, добавив прозрачность к барам.

ggplot(data, aes(fill=A, y=value, x=B)) + 
  geom_bar(stat="identity", position=position_dodge(), alpha=0.3)

enter image description here

Похоже, вы действительно пытаетесь сделать следующее (но пусть я знаю, если я неправильно понял):

pd = position_dodge(0.92)

data %>% 
  group_by(A,B) %>% 
  summarise(mean=mean(value), sd=sd(value)) %>% 
  ggplot(aes(fill=A, x=B)) + 
  geom_col(aes(y=mean), position=pd)+
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), position=pd, width=0.2)

enter image description here

Фасеткой является еще один вариант:

data %>% 
  group_by(A,B) %>% 
  summarise(mean=mean(value), sd=sd(value)) %>% 
  ggplot(aes(x=A)) + 
    geom_col(aes(y=mean), fill=hcl(240,100,65)) +
    geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), width=0.2) +
    facet_grid(. ~ B, labeller=label_both, space="free_x", scales="free_x")

enter image description here

Но вам действительно нужны бары?

data %>% 
  group_by(A,B) %>% 
  summarise(mean=mean(value), sd=sd(value)) %>% 
  ggplot(aes(x=A)) + 
  geom_pointrange(aes(y=mean, ymin=mean-sd, ymax=mean+sd), shape=21, fill="red", 
                  fatten=6, stroke=0.3) +
  facet_grid(. ~ B, labeller=label_both, space="free_x", scales="free_x")

Мы также можем сделать этот расчет в ggplot, используя stat_summary:

data %>% 
  ggplot(aes(x=A, y=value)) + 
  stat_summary(fun.data=mean_sdl, fun.args=list(mult=1), geom="pointrange", 
               shape=21, fill="red", fatten=6, stroke=0.3) +
  facet_grid(. ~ B, labeller=label_both, space="free_x", scales="free_x")

В любом случае, сюжет выглядит так:

enter image description here

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