我想创建一个看起来像这样的Likert图:
我的数据框中有两列 - 年龄和总体满意度,两者都是因素。每个年龄段的人数不均匀。我想制作一个类似上图的情节,但情节中的每个条形代表不同的年龄范围。上面的图是使用likert
包创建的,但似乎不能有不同数量的受访者。
df <- structure(list(Age = c("50-55 yrs", "35-40 yrs", "25-30 yrs",
"45-50 yrs", "45-50 yrs", "20-25 yrs", "55-60 yrs", "55-60 yrs",
"50-55 yrs", "45-50 yrs", "50-55 yrs", "55-60 yrs", "55-60 yrs",
"65+ yrs", "60-65 yrs", "55-60 yrs", "35-40 yrs", "50-55 yrs",
"45-50 yrs", "40-45 yrs", "45-50 yrs", "40-45 yrs", "30-35 yrs",
"40-45 yrs", "45-50 yrs", "45-50 yrs", "30-35 yrs", "50-55 yrs",
"40-45 yrs", "25-30 yrs"), OverallSatisfaction = c("Dissatisfied",
"Dissatisfied", "Satisfied", "Very Dissatisfied", "Satisfied",
"Neutral", "Dissatisfied", "Very Dissatisfied", "Very Dissatisfied",
"Very Dissatisfied", "Very Dissatisfied", "Satisfied", "Satisfied",
"Satisfied", "Satisfied", "Satisfied", "Neutral", "Neutral",
"Neutral", "Neutral", "Dissatisfied", "Dissatisfied", "Dissatisfied",
"Dissatisfied", "Dissatisfied", "Dissatisfied", "Dissatisfied",
"Neutral", "Dissatisfied", "Neutral")), row.names = c(NA, 30L
), class = "data.frame")
如何在likert
包或ggplot2
中的一个因子内按水平分割出条形图?
我尝试过以下方法:
ggplot(AgeSat.df, aes(y = OverallSatisfaction, x = Age), position = "stack") +
geom_col(aes(fill = OverallSatisfaction)) +
coord_flip()
但我想要的是在中心和底部轴(在coord_flip之后的x)中显示中性点,如上面的相似示例中所示。
如果您将数据转换为宽格式,即使年龄组的大小不同,plot.likert
也可以绘制它。
library("tidyverse")
library("likert")
# Load your example data here....
ages <- sort(unique(df$Age))
satisfaction <- c("Very Dissatisfied", "Dissatisfied", "Neutral",
"Satisfied", "Very Satisfied")
# Commented out because it is redundant
# df$Age <- factor(df$Age, levels = ages)
df$OverallSatisfaction <- factor(df$OverallSatisfaction,
levels = satisfaction)
items <- df %>%
# Need to add an `id` column or `tidyr::spread` will complain.
mutate(id = row_number()) %>%
spread(Age, OverallSatisfaction) %>%
# Need to remove `id` column or `likert::likert` will complain.
select(-id)
plot(likert(items), type = "bar")
# If you want to specify how to sort the age groups
plot(likert(items), type = "bar", group.order = ages)
# or
plot(likert(items), type = "bar", group.order = rev(ages))
由reprex package创建于2019-03-04(v0.2.1)
这是一种有点“hacky”的方法,归结为以类似于likert
对象的方式重新格式化数据,然后使用plot.likert
绘制。
library(tidyverse)
res <- df %>%
group_by(Age, OverallSatisfaction) %>%
tally() %>%
group_by(Age) %>%
transmute(
OverallSatisfaction,
frac = n / sum(n) * 100) %>%
spread(OverallSatisfaction, frac, fill = 0) %>%
ungroup() %>%
mutate(Age = factor(Age)) %>%
rename(Item = Age) %>%
as.data.frame()
items <- df %>%
group_by(Age) %>%
mutate(n = 1:n()) %>%
spread(Age, OverallSatisfaction) %>%
select(-n) %>%
mutate_all(~factor(., levels = levels(factor(df$OverallSatisfaction)))) %>%
as.data.frame()
# Manually construct likert object from res and items
library(likert)
data <- list(
results = res,
items = items,
nlevels = length(names(res)[-1]),
levels = names(res)[-1])
class(data) <- "likert"
# Plot using plot.likert
plot(data)
我们可以将结果与简单的table
调用结果进行比较
table(df$Age, df$OverallSatisfaction)
# Dissatisfied Neutral Satisfied Very Dissatisfied
#20-25 yrs 0 1 0 0
#25-30 yrs 0 1 1 0
#30-35 yrs 2 0 0 0
#35-40 yrs 1 1 0 0
#40-45 yrs 3 1 0 0
#45-50 yrs 3 1 1 2
#50-55 yrs 1 2 0 2
#55-60 yrs 1 0 3 1
#60-65 yrs 0 0 1 0
#65+ yrs 0 0 1 0