#r #ggplot2 #dplyr #stacked #stackedbarseries
#r #ggplot2 #dplyr #сложенный #stackedbarseries
Вопрос:
Тот же график из необработанных и обобщенных данных
Для следующей структуры данных
dsN<-data.frame(
id=rep(1:100, each=4),
yearF=factor(rep(2001:2004, 100)),
attendF=sample(1:8, 400, T, c(.2,.2,.15,.10,.10, .20, .15, .02))
)
dsN[sample(which(dsN$yearF==2001), 5), "attendF"]<-NA
dsN[sample(which(dsN$yearF==2002), 10), "attendF"]<-NA
dsN[sample(which(dsN$yearF==2003), 15), "attendF"]<-NA
dsN[sample(which(dsN$yearF==2004), 20), "attendF"]<-NA
attcol8<-c("Never"="#4575b4",
"Once or Twice"="#74add1",
"Less than once/month"="#abd9e9",
"About once/month"="#e0f3f8",
"About twice/month"="#fee090",
"About once/week"="#fdae61",
"Several times/week"="#f46d43",
"Everyday"="#d73027")
dsN$attendF<-factor(dsN$attendF, levels=1:8, labels=names(attcol8))
head(dsN,13)
id yearF attendF
1 1 2001 About once/week
2 1 2002 About once/month
3 1 2003 About once/week
4 1 2004 <NA>
5 2 2001 Less than once/month
6 2 2002 About once/week
7 2 2003 About once/week
8 2 2004 Several times/week
9 3 2001 Once or Twice
10 3 2002 About once/week
11 3 2003 <NA>
12 3 2004 Once or Twice
13 4 2001 Several times/week
мы можем получить серию сложенных гистограмм
require(ggplot2)
# p<- ggplot( subset(dsN,!is.na(attendF)), aes(x=yearF, fill=attendF)) # leaving NA out of
p<- ggplot( dsN, aes(x=yearF, fill=attendF)) # keeping NA in calculations
p<- p geom_bar(position="fill")
p<- p scale_fill_manual(values = attcol8,
name="Response category" )
p<- p scale_y_continuous("Prevalence: proportion of total",
limits=c(0, 1),
breaks=c(.1,.2,.3,.4,.5,.6,.7,.8,.9,1))
p<- p scale_x_discrete("Waves of measurement",
limits=as.character(c(2000:2005)))
p<- p labs(title=paste0("In the past year, how often have you attended a worship service?"))
p
Приведенный выше график создан из необработанных данных. Однако иногда
удобно создавать графики из обобщенных данных, особенно если
требуется контроль над статистическими функциями. Ниже приведено преобразование dsN
в ds, которое содержит только те значения, которые фактически отображаются на
графике выше:
require(dplyr)
ds<- dsN %.%
dplyr::filter(!is.na(attendF)) %.%
dplyr::group_by(yearF,attendF) %.%
dplyr::summarize(count = sum(attendF)) %.%
dplyr::mutate(total = sum(count),
percent= count/total)
head(ds,10)
Source: local data frame [10 x 5]
Groups: yearF
yearF attendF count total percent
1 2001 Never 18 373 0.04826
2 2001 Once or Twice 36 373 0.09651
3 2001 Less than once/month 30 373 0.08043
4 2001 About once/month 32 373 0.08579
5 2001 About twice/month 40 373 0.10724
6 2001 About once/week 90 373 0.24129
7 2001 Several times/week 119 373 0.31903
8 2001 Everyday 8 373 0.02145
9 2002 Never 11 355 0.03099
10 2002 Once or Twice 44 355 0.12394
# verify
summarize(filter(ds, yearF==2001), should.be.one=sum(percent))
```
Source: local data frame [1 x 2]
yearF should.be.one
1 2001 1
Вопрос:
Как можно воссоздать график сверху, используя этот сводный набор ds
данных?
Ответ №1:
Ну, часть проблемы заключается в том, что ваше подведение итогов неверно. Вам нужно оставить значения NA там, если вы хотите правильно учесть их в общей сумме. Возможно, попробуйте
ds<- dsN %.%
dplyr::group_by(yearF,attendF) %.%
dplyr::summarize(count = length(attendF)) %.%
dplyr::mutate(total = sum(count, na.rm=T),
percent= count/total)
Затем, чтобы использовать обобщенные данные, вам нужно лишь немного изменить первые две строки
p<- ggplot( ds, aes(x=yearF, y=percent, fill=attendF)) # keeping NA in calculations
p<- p geom_bar(position="stack", stat="identity")
Обратите внимание, что мы добавляем определенное y
значение и указываем geom_bar использовать stat="identity"
, что означает использовать фактические y
значения, которые мы указали в качестве высоты. И они, они будут создавать одно и то же изображение
Комментарии:
1. Вы правы. Я все еще не понимаю dplyr. Проблема NA не является неправильной / правильной, а вытекает из цели анализа (я описываю в обновлении). Синтаксис ggplot был именно тем, что мне было нужно. Спасибо!
Ответ №2:
Ответ из комментария 1
Как указал @MrFlick, ошибка была в формулах вычисления в summary() . Однако вопрос о том, следует ли оставлять пропущенные значения при вычислении общего числа, является значимым исследовательским решением. Если мы хотим оставить NA
в расчете общее:
ds<- dsN %.%
# dplyr::filter(!is.na(attendF)) %.% # comment out to count NA in the total
dplyr::group_by(yearF,attendF) %.%
dplyr::summarize(count = length( attendF)) %.%
dplyr::mutate(total = sum(count),
percent= count/total)
head(ds,10)
Source: local data frame [10 x 5]
Groups: yearF
yearF attendF count total percent
1 2001 Never 23 100 0.23
2 2001 Once or Twice 9 100 0.09
3 2001 Less than once/month 16 100 0.16
4 2001 About once/month 11 100 0.11
5 2001 About twice/month 3 100 0.03
6 2001 About once/week 21 100 0.21
7 2001 Several times/week 9 100 0.09
8 2001 Everyday 3 100 0.03
9 2001 NA 5 100 0.05
10 2002 Never 17 100 0.17
Пропущенные значения используются при расчете общего количества ответов, чтобы показать
естественное истощение в исследовании.
p<- ggplot( ds, aes(x=yearF, y=percent, fill=attendF)) # keeping NA in calculations
p<- p geom_bar(position="stack", stat="identity")
p<- p scale_fill_manual(values = attcol8,
name="Response category" )
p<- p scale_y_continuous("Prevalence: proportion of total",
limits=c(0, 1),
breaks=c(.1,.2,.3,.4,.5,.6,.7,.8,.9,1))
p<- p scale_x_discrete("Waves of measurement",
limits=as.character(c(2000:2005)))
p<- p labs(title=paste0("In the past year, how often have you attended a worship service?"))
p
Однако, предполагая, что истощение не связано существенным образом с
показателем результата, было бы интересно посмотреть, как относительная
распространенность одобрения ответов меняется со временем или, возможно, остается
в равновесии. Для этого нам нужно удалить пропущенные значения из
вычисления общего количества ответов:
ds<- dsN %.%
dplyr::filter(!is.na(attendF)) %.% # comment out to count NA in the total
dplyr::group_by(yearF,attendF) %.%
dplyr::summarize(count = length( attendF)) %.%
dplyr::mutate(total = sum(count),
percent= count/total)
head(ds,10)
Source: local data frame [10 x 5]
Groups: yearF
yearF attendF count total percent
1 2001 Never 23 95 0.24211
2 2001 Once or Twice 9 95 0.09474
3 2001 Less than once/month 16 95 0.16842
4 2001 About once/month 11 95 0.11579
5 2001 About twice/month 3 95 0.03158
6 2001 About once/week 21 95 0.22105
7 2001 Several times/week 9 95 0.09474
8 2001 Everyday 3 95 0.03158
9 2002 Never 17 90 0.18889
10 2002 Once or Twice 23 90 0.25556
График отражает это соответствующим образом:
p<- ggplot( ds, aes(x=yearF, y=percent, fill=attendF)) # keeping NA in calculations
p<- p geom_bar(position="stack", stat="identity")
p<- p scale_fill_manual(values = attcol8,
name="Response category" )
p<- p scale_y_continuous("Prevalence: proportion of total",
limits=c(0, 1),
breaks=c(.1,.2,.3,.4,.5,.6,.7,.8,.9,1))
p<- p scale_x_discrete("Waves of measurement",
limits=as.character(c(2000:2005)))
p<- p labs(title=paste0("In the past year, how often have you attended a worship service?"))
p
Спасибо, @MrFlick!