李克特风格的情节在一个因素内按水平分割

问题描述 投票:1回答:2

我想创建一个看起来像这样的Likert图:

Example Likert plot produced with the Likert package

我的数据框中有两列 - 年龄和总体满意度,两者都是因素。每个年龄段的人数不均匀。我想制作一个类似上图的情节,但情节中的每个条形代表不同的年龄范围。上面的图是使用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)中显示中性点,如上面的相似示例中所示。

r ggplot2 graphing likert
2个回答
2
投票

如果您将数据转换为宽格式,即使年龄组的大小不同,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)


2
投票

这是一种有点“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)

enter image description here

我们可以将结果与简单的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
© www.soinside.com 2019 - 2024. All rights reserved.