【问题标题】:How to group dots and limit number of dots per column with categorical data in geom_dotplot?如何使用 geom_dotplot 中的分类数据对点进行分组并限制每列的点数?
【发布时间】:2020-07-27 02:42:01
【问题描述】:

我想生成一个包含 3 个类别的分类数据点图,以显示三个类别中每个类别的个体数量。我希望第一个类别(“类型”)位于 y 轴上,水平线分隔每种类型,点堆叠在线上,第二个类别(性别)位于 x 轴上,第三个类别( disease) 作为填充颜色。

我无法让点正确分组或堆叠,当我让它们正确分组时,它们都在一个太高的长列中,所以我希望这些点最多堆叠到五个点,然后继续一个新的列。

这里是重现数据的代码:

df1 <- data.frame(sex="female", disease="yes", type="B") 
df2 <- data.frame(sex="female", disease="yes", type="C") 
df3 <- data.frame(sex="female", disease="no", type="B") 
df4 <- data.frame(sex="male", disease="yes", type="A") 
df5 <- data.frame(sex="male", disease="yes", type="B") 
df6 <- data.frame(sex="male", disease="yes", type="C") 
df7 <- data.frame(sex="male", disease="no", type="A") 
df8 <- data.frame(sex="male", disease="no", type="B") 
df9 <- data.frame(sex="male", disease="no", type="C") 
df10 <- data.frame(sex="male", disease="no", type="D") 
df2 <-df2[rep(nrow(df2), each = 3), ]
df3 <-df3[rep(nrow(df3), each = 29), ]
df5 <-df5[rep(nrow(df5), each = 3), ]
df8 <-df8[rep(nrow(df8), each = 35), ]
df9 <-df9[rep(nrow(df9), each = 7), ]
df.all<-rbind(df1, df2, df3, df4, df5, df6, df7, df8, df9, df10)

这是我目前所拥有的,但是点堆叠的方向错误并且重叠,我希望它们是五个点的堆叠。:

g<-ggplot(data=df.all)+
geom_dotplot(aes(x=sex, y=type, fill=disease),
binaxis= "y", 
stackgroups = F,
dotsize = 1,
stackdir = "up",
)
g

这是我试图制作的那种情节(但使用我的实际数据):

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    当我看到你的模拟情节时,我立刻想到了waffle charts。这可能与您的想法完全不同,但也许它会给您一些想法。

    1. 我们首先重新格式化您的样本数据:将字符列转换为因子列,根据我们在图中的最终顺序设置级别,然后添加计数。然后,我们按照 typesex 组合嵌套数据。
    library(tidyverse)
    df <- df.all %>%
        count(sex, type, disease) %>%
        mutate_if(is.character, as.factor) %>%
        mutate(
            sex = factor(sex, levels = rev(levels(sex))),
            disease = factor(disease, levels = rev(levels(disease)))) %>%
        complete(type, nesting(disease, sex), fill = list(n = 0)) %>%
        group_by(sex, type) %>%
        nest()
    
    1. 我们现在为每个typesex 生成一个waffle::waffle,并将ggplot 对象存储在list 中。
    library(waffle)
    lst <- df %>%
        mutate(data = map(
            data, ~ .x %>%
                deframe() %>%
                waffle(
                    rows = 5, 
                    size = 1, 
                    colors=c("#c7d4b6", "#a3aabd")) +
                theme(legend.position = "none"))) %>%
        pull(data)
    
    1. 我们现在将绘图对象布置在网格中并添加列和行标签(在 this post 的帮助下)
    library(gridExtra)
    library(grid)
    combine <- rbind(
        tableGrob(
            t(df %>% pull(sex) %>% levels), theme = ttheme_minimal(), rows = ""), 
        cbind(tableGrob(
            df %>% pull(type) %>% levels, theme = ttheme_minimal()), 
            arrangeGrob(grobs = lst, ncol = 2),  size = "last"), size = "last")
    grid.newpage()
    grid.draw(combine)
    

    【讨论】:

    • 我真的很喜欢这个,有没有办法让起始块向左对齐,让每个类别中最左边的块相互对齐?并用水平线分隔类型?
    • @stanley 恐怕我对你的任何一个问题都没有答案。我曾想过/希望调整绘图对象的对齐方式不会太难,但我无法解决。据我所知,这两个请求都需要一些低级的 grob 操作。我研究的另一种方法是使用geom_wafflefacet_grid 来构建情节。不幸的是,waffle 似乎有一个bug that prevents the use of geom_waffle with facet_grid。 [...]
    • [继续] 也许一个前进的方法是与waffle 代码作者 (Bob Rudis) 一起解决这个问题。如果您可以让waffle/geom_wafflefacet_grid 一起工作,则可以避免所有手动 grob 操作,让ggplot 通过构面正确处理网格布局。
    猜你喜欢
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2017-05-17
    • 2016-12-21
    相关资源
    最近更新 更多