繁体   English   中英

R- Bar plot 具有连续的 x 和 y

[英]R- Bar plot with continuous x and y

如果这个问题已经得到回答,请链接,因为我无法找到类似的问题。 I have referred to R bar plot with 3 variables , Bar plot with multiple variables in R , ggplot with 2 y axes on each side and different scales , Bar Plot with 2 y axes and same x axis in R language [duplicate] , Bar Plot具有 2 个 Y 轴和相同的 X 轴

我有一个数据集,其中包括物种、观察值、预期值以及观察值和预期值的标准化值。

data <- structure(list(Species = c("BABO_BW", "BABO_BW", "BABO_BW", "BABO_RC", 
"BABO_RC", "BABO_RC", "BABO_SKS", "BABO_SKS", "BABO_SKS", "BABO_MANG", 
"BABO_MANG", "BABO_MANG", "BW_RC", "BW_RC", "BW_RC", "BW_SKS", 
"BW_SKS", "BW_SKS", "BW_MANG", "BW_MANG", "BW_MANG", "RC_SKS", 
"RC_SKS", "RC_SKS", "RC_MANG", "RC_MANG", "RC_MANG", "SKS_MANG", 
"SKS_MANG", "SKS_MANG"), variable = c("obs.C-score", "exp.C-score", 
"SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", "obs.C-score", 
"exp.C-score", "SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", 
"obs.C-score", "exp.C-score", "SES_Cscore", "obs.C-score", "exp.C-score", 
"SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", "obs.C-score", 
"exp.C-score", "SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", 
"obs.C-score", "exp.C-score", "SES_Cscore"), value = c(328680, 
276507, 6.73358774036271, 408360, 345488, 5.31345024375997, 285090, 
254670, 4.35376633657727, 12474, 12190, 1.24624427424057, 1450800, 
1809738, -11.0195450589776, 1507488, 1361088, 6.15672144449049, 
62706, 65780, -0.495728742814285, 1790156, 1700165, 2.70409191051284, 
45701, 86301, -4.71151949799025, 42240, 62745, -4.52203636797869
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-30L))

样品 Output

    Species    Variable       Value
1   BABO_BW    obs.C-score    328680.0000000
2   BABO_BW    exp.C-score    276507.0000000
3   BABO_BW    SES_Cscore     6.7335877
4   BABO_MANG  obs.C-score    12474.0000000
5   BABO_MANG  exp.C-score    12190.0000000
6   BABO_MANG  SES_Cscore     1.2462443
7   BABO_RC    obs.C-score    408360.0000000
8   BABO_RC    exp.C-score    345488.0000000
9   BABO_RC    SES_Cscore     5.3134502
10  BABO_SKS   obs.C-score    285090.0000000

我试图将 SES_Cscore 放在 x 轴上,并将 obs.C-score 和 exp.C-score 作为条形。 物种列对 C 分数进行了分组,因此我也想将它们包括在 x 轴中。

我已经能够将 plot 处的物种和其他变量作为条形图。

ggplot(data,aes(x = Species,y = value)) + 
    geom_bar(aes(fill = variable),stat = "identity",position = "dodge")

图表不正确

我想在 x 轴上也有 SES_Cscore 的连续变量。 有没有办法做到这一点?

提前谢谢你,祝你有美好的一天!

这可以通过稍微重塑数据来完成,以便 SES_Score 被记录为每个物种一个值的变量,而不是作为每个观察映射到条形高度的变量。 我在这里通过重塑宽(以便三个变量每个都有自己的列)来做到这一点,然后再次重塑长但仅限于我们想要 map 到 y 的变量。

library(tidyverse)
data %>%
  pivot_wider(names_from = variable, values_from = value) %>%
  pivot_longer(2:3) %>%
  mutate(Species2 = paste(Species, round(SES_Cscore,digits = 2), sep = "\n") %>%
           fct_reorder(SES_Cscore)) -> data2

data2
## A tibble: 20 × 5
#   Species   SES_Cscore name          value Species2         
#   <chr>          <dbl> <chr>         <dbl> <fct>            
# 1 BABO_BW        6.73  obs.C-score  328680 "BABO_BW\n6.73"  
# 2 BABO_BW        6.73  exp.C-score  276507 "BABO_BW\n6.73"  
# 3 BABO_RC        5.31  obs.C-score  408360 "BABO_RC\n5.31"  
# 4 BABO_RC        5.31  exp.C-score  345488 "BABO_RC\n5.31"  
# 5 BABO_SKS       4.35  obs.C-score  285090 "BABO_SKS\n4.35" 
# etc.

我们可以通过将其连接到我们想要的 map 到 y 的观察结果和我们想要用于每个物种的 x position 的观察结果之间,以一种可能对大数据更有效的方式交替地实现不同的重塑:

left_join(data %>% filter(variable != "SES_Cscore"),
          data %>% filter(variable == "SES_Cscore") %>%
            transmute(Species, x_val = value,
                      Species_label = paste(Species, sprintf(value, 
                        fmt = "%#.2f"), sep = "\n") %>% fct_reorder(value))) 

重塑后,更直接地获得按每个物种的 SES_Cscore 排序的 plot:

ggplot(data2, aes(Species2, value, fill = name)) +
  geom_col(position = "dodge")

在此处输入图像描述


如果您想要 plot 具有与 SES_Cscore 相关的连续 x 轴,您可能会遇到一些图形设计挑战,因为在某些情况下数据可能会聚集在一起。 请注意默认条形宽度是如何被压缩的,以便 ggplot 可以防止第二和第三种条形图重叠。

这种方法也需要更多的工作,因为 ggplot 的轴适用于离散(分类)数据或连续数据,并且没有设计用于管理组合的默认值,分类数据是连续映射的。 所以你必须恢复到某种geom_text来制作手动标签,如果你想让它们看起来更像普通的轴标签,还需要进行一些定制。

ggplot(data2, aes(SES_Cscore, value, fill = name)) +
  geom_col(position = "dodge") +
  ggrepel::geom_text_repel(aes(y = 0, label = Species), 
                           angle = 90, direction = "x", hjust = 0, lineheight = 0.8, size = 3,
                           data = data2 %>% distinct(Species, .keep_all = TRUE))

在此处输入图像描述

在前面,缩放数据并使用第二个轴可能会在视觉上歪曲数据:不难快速查看这个 plot 并推断出蓝色条的值与红色/绿色条的含义相同。

话虽如此,试试这个:

library(ggplot2)
library(dplyr)
fac <- 50000
mycolors <- c("obs.C-score" = "red", "exp.C-score" = "green", "SES_Cscore" = "blue")
data %>%
  mutate(value = value * ifelse(variable == "SES_Cscore", fac, 1)) %>%
  ggplot(aes(x = Species, y = value)) +
  geom_bar(aes(fill = variable), stat = "identity", position = "dodge") +
  scale_y_continuous(
    sec.axis = sec_axis(name = "SES_Cscore", ~ . / fac),
    breaks = ~ scales::extended_breaks()(pmax(0, .))
  ) +
  scale_color_manual(values = mycolors) +
  theme(
    axis.title.y.right = element_text(color = mycolors["SES_Cscore"]),
    axis.text.y.right = element_text(color = mycolors["SES_Cscore"]),
    axis.ticks.y.right = element_line(color = mycolors["SES_Cscore"])
  )

带第二轴的ggplot

我在第二个(右)轴上使用蓝色 colors 来尝试在视觉上将它与蓝色条配对。 根据我对数据的推断,我还冒昧地将主轴(左)保持在 0 或更大; 根本不需要。 另外,我可以省略scale_color_manual(.)并假设使用element_text(color="blue")是正确的; 如果/当您的数据在variable中以更少或更多级别发生变化时,那将失败,所以我手动控制它们......我尝试为第二个轴上的所有内容分配正确的颜色:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM