在带有垂直线的水平条中绘制方法

plotting means in a horizontal bar with a vertical line

ID score1 score 2 score 3 score 4
1 200 300 400 -200
2 250 -310 -470 -200
3 210 400 480 -200
4 220 -10 -400 -200
5 150 -50 400 -200

我是 R 的新手,我想制作一个图表来显示每个分数的平均值。 然而,分数在 Y 轴上排列,并且有一条垂直线代表 0。 每个分数均高于零,从中央到右边出现一个水平条。 每个低于零的分数均值从中央到左侧出现一个水平条。 感谢您的帮助!

您可以先将数据集转换为长格式,然后再计算每个分数的均值,从而达到您想要的结果。在这些数据整理步骤之后,您可以使用 ggplot2 通过 geom_col 绘制均值,并使用 geom_vline:

添加垂直零线
df <- data.frame(
          ID = c(1L, 2L, 3L, 4L, 5L),
      score1 = c(200L, 250L, 210L, 220L, 150L),
     score.2 = c(300L, -310L, 400L, -10L, -50L),
     score.3 = c(400L, -470L, 480L, -400L, 400L),
     score.4 = c(-200L, -200L, -200L, -200L, -200L)
)

library(dplyr)
library(tidyr)
library(ggplot2)

df1 <- df |> 
  tidyr::pivot_longer(-ID, names_to = "score") |> 
  group_by(score) |> 
  summarise(value = mean(value))

ggplot(df1, aes(value, score)) +
  geom_vline(xintercept = 0) +
  geom_col()

编辑 要标记条形图,您可以使用 geom_text。棘手的部分是对齐标签。为此,我使用 ifelse 在正均值的情况下右对齐 (hjust = 1) 标签,在负均值的情况下左对齐 (hjust = 0)。实际上我做了 1.1 和 -.1 来在标签和栏之间添加一些填充。轴标签可以通过比例尺的 labels 参数设置,在您的情况下它是 scale_y_discrete。我个人更喜欢使用命名向量,它将标签分配给数据中的类别。

ggplot(df1, aes(value, score)) +
  geom_vline(xintercept = 0) +
  geom_col() +
  geom_text(aes(label = value, hjust = ifelse(value > 0, 1.1, -.1)), color = "white") +
  scale_y_discrete(labels = c("score1" = "Test1", "score.2" = "Test2", "score.3" = "Test3", "score.4" = "Test4"))

与 stefan 的方法类似,但函数选择略有不同:

  1. 数据:
dat <- structure(list(ID = 1:5, score1 = c(200L, 250L, 210L, 220L, 150L
), score2 = c(300L, -310L, 400L, -10L, -50L), score3 = c(400L, 
-470L, 480L, -400L, 400L), score4 = c(-200L, -200L, -200L, -200L, 
-200L)), class = "data.frame", row.names = c(NA, -5L))
  1. 函数链
dat %>% 
  select(-ID) %>% 
  map_df(mean) %>% 
  pivot_longer(everything(), names_to = "score", values_to = "means") %>%
  ggplot() + 
  coord_flip() + 
  geom_col(aes(x = score, y = means))
  1. 结果

如果您想将刻度标记上的标签(“分数 1”、“分数 2”等)更改为其他标签,您可以使用 scale_x_discrete。 此外,如果您想在每个栏的顶部显示数值,您可以使用 geom_texthjust 来调整标签位置。

例如:

dat %>% 
  select(-ID) %>% 
  map_df(mean) %>% 
  pivot_longer(everything(), names_to = "score", values_to = "means") %>%
  ggplot() + 
  coord_flip() + 
  geom_col(aes(x = score, y = means)) + 
  scale_x_discrete(labels = c("Test A", "Test B", "Test C", "Test D")) +
  geom_text(aes(x = score, y = means, label = means), 
            hjust = c(-0.5, -0.5, -0.5, 1.1))