R 在ggplot2中叠加/叠加分组条形图
我想做一个条形图,展示两个时间点“之前”和“之后”的数据叠加 在每个时间点,参与者被问到两个问题(“疼痛”和“恐惧”),他们会回答1分、2分或3分 我现有的代码很好地绘制了“before”时间点的数据计数,但我似乎无法添加“after”数据的计数 这是我希望添加“after”数据的绘图的草图,黑色条表示“after”数据: 我想在ggplot2()中进行绘图,并且我已经尝试从中改编代码,但无法使其用于分组数据 非常感谢R 在ggplot2中叠加/叠加分组条形图,r,ggplot2,R,Ggplot2,我想做一个条形图,展示两个时间点“之前”和“之后”的数据叠加 在每个时间点,参与者被问到两个问题(“疼痛”和“恐惧”),他们会回答1分、2分或3分 我现有的代码很好地绘制了“before”时间点的数据计数,但我似乎无法添加“after”数据的计数 这是我希望添加“after”数据的绘图的草图,黑色条表示“after”数据: 我想在ggplot2()中进行绘图,并且我已经尝试从中改编代码,但无法使其用于分组数据 非常感谢 #DATA PREP library(dplyr) library(ggp
#DATA PREP
library(dplyr)
library(ggplot2)
library(tidyr)
df <- data.frame(before_fear=c(1,1,1,2,3),before_pain=c(2,2,1,3,1),after_fear=c(1,3,3,2,3),after_pain=c(1,1,2,3,1))
df <- df %>% gather("question", "answer_option") # Get the counts for each answer of each question
df2 <- df %>%
group_by(question,answer_option) %>%
summarise (n = n())
df2 <- as.data.frame(df2)
df3 <- df2 %>% mutate(time = factor(ifelse(grepl("before", question), "before", "after"),
c("before", "after"))) # change classes and split data into two data frames
df3$n <- as.numeric(df3$n)
df3$answer_option <- as.factor(df3$answer_option)
df3after <- df3[ which(df3$time=='after'), ]
df3before <- df3[ which(df3$time=='before'), ]
# CODE FOR 'BEFORE' DATA ONLY PLOT - WORKS
ggplot(df3before, aes(fill=answer_option, y=n, x=question)) + geom_bar(position="dodge", stat="identity")
# CODE FOR 'BEFORE' AND 'AFTER' DATA PLOT - DOESN'T WORK
ggplot(mapping = aes(x, y,fill)) +
geom_bar(data = data.frame(x = df3before$question, y = df3before$n, fill= df3before$index_value), width = 0.8, stat = 'identity') +
geom_bar(data = data.frame(x = df3after$question, y = df3after$n, fill=df3after$index_value), width = 0.4, stat = 'identity', fill = 'black') +
theme_classic() + scale_y_continuous(expand = c(0, 0))
#数据准备
图书馆(dplyr)
图书馆(GG2)
图书馆(tidyr)
df%
总结(n=n())
df2我认为线索是设置“after”条的宽度
,但要避开它们,就好像它们的宽度是0.9(即与“before”条相同的(默认)宽度)。此外,由于我们没有映射“after”栏的填充
,因此我们需要使用组
美学来实现回避
我更喜欢只使用一个数据集,并在每次调用geom\u col
时将其子集
ggplot(mapping = aes(x = question, y = n, fill = factor(ans))) +
geom_col(data = d[d$t == "before", ], position = "dodge") +
geom_col(data = d[d$t == "after", ], aes(group = ans),
fill = "black", width = 0.5, position = position_dodge(width = 0.9))
数据:
预先计算计数,并按上述操作进行geom\u col
# d2 <- d[ , .N, by = .(question, ans)]
数据:
df我的解决方案与@Henrik的非常相似,但我想指出几点
首先,您正在geom\u col
s中构建数据帧,这可能比您需要的更混乱。如果您已经创建了df3after
等,那么您最好在ggplot
中使用它
其次,我很难跟上你的整理工作。我认为有两个tidyr
函数可以让您更轻松地完成这项任务,因此我采用了不同的方法,例如使用separate
创建time
和measure
列,而不是手动搜索它们,从而使其更具可扩展性。这也可以让你在x轴上放置“痛苦”和“恐惧”,而不是仍然有“之前的痛苦”和“之前的恐惧”,一旦你在绘图上有了“之后”值,它们就不再是准确的表示。但是你可以无视这一点,坚持你自己的方法
库(tidyverse)
df%
变异(答案选项=as.因子(答案选项))%>%
计数(问题、答案选项)%>%
分开(问题,分为=c(“时间”,“测量”),sep=“”,remove=F)
德福朗
#>#tibble:12 x 5
#>问题时间测量答案选项n
#>
#>一个接一个的恐惧
#>一次又一次的恐惧2 1
#>一次又一次的恐惧
#>4后痛后痛1 3
#>5后痛后痛2 1
#>6术后疼痛3 1
#>7先于恐惧1先于恐惧3
#>先恐惧后恐惧2 1
#>9在恐惧之前3 1
#>10先于痛1先于痛2
#>11前痛2前痛2
#>12前痛3前痛1
正如您所做的,我将其拆分为前后数据集,然后用2geom_col
s绘制它们。我仍然将df_long
放入ggplot
,几乎将其视为一个假人,以获得统一的x和y美学效果。就像@Henrik所说的,你可以在geom_col
和它的position_dodge
中使用不同的width
来避开宽度为90%的栅栏,但栅栏本身的宽度只有40%
df_在%filter之前(时间==“之前”)
百分比过滤器后的df_(时间=“之后”)
ggplot(df_long,aes(x=measure,y=n))+
地理坐标(aes(填充=回答选项),
数据=之前的df_,宽度=0.9,
位置=位置\减淡(宽度=0.9))+
地理坐标(aes(组=答案选项),
数据=df_后,填充=“黑色”,宽度=0.4,
位置=位置\减淡(宽度=0.9))
您可以在每个geom\u col
内部进行过滤,而不是制作两个单独的数据帧。这通常是我的偏好,除非过滤更复杂。此代码将获得与上面相同的绘图
ggplot(df_long,aes(x=measure,y=n))+
地理坐标(aes(填充=回答选项),
数据=.%>%过滤器(时间=“之前”),宽度=0.9,
位置=位置\减淡(宽度=0.9))+
地理坐标(aes(组=答案选项),
数据=.%>%过滤器(时间=“之后”),填充=“黑色”,宽度=0.4,
位置=位置\减淡(宽度=0.9))
library(data.table)
d <- melt(setDT(df), measure.vars = names(df), value.name = "ans")
d[ , c("t", "question") := tstrsplit(variable, "_")]
# d2 <- d[ , .N, by = .(question, ans)]
ggplot(mapping = aes(x = question, fill = factor(ans))) +
geom_bar(data = d[d$t == "before", ], position = "dodge") +
geom_bar(data = d[d$t == "after", ], aes(group = ans),
fill = "black", width = 0.5, position = position_dodge(width = 0.9))
df <- data.frame(before_fear = c(1,1,1,2,3), before_pain = c(2,2,1,3,1),
after_fear = c(1,3,3,2,3),after_pain = c(1,1,2,3,1))