r-宽格式,导致ggplot中的条形图数据加倍



在用宽格式的数据创建覆盖条形图的过程中,我注意到我的条形图值正在翻倍。

快速解决方法是简单地将值除以2

但到底是什么原因导致了这种情况的发生?

# Data
status <- c("Infected","Not Infected")
female <- c(0.3,0.7)
male <- c(0.8,0.2)
# Colors
dark <- '#008AFE' # blue
lightest <-'#CCE8FF'
light_accent <-'#FFCB93' #peachy
lightest_accent <- '#FFE5C9'

df <- data.frame("Covid" = status,"female_perc" = female, "male_perc" = male)

gender_claim <- ggplot() +
geom_col(data = df, 
mapping= aes(x = c("Male"), y = male_perc[2]/2), 
fill = light_accent, width = .25) +
geom_col(data = df, 
mapping= aes(x = c("Male"), y = male_perc[1]/2), 
fill = lightest, width = .15) +
scale_y_continuous(limits = c(0, 1), breaks = seq(0, 1, by = .25),
labels = function(y) paste0(round(y*100,0),"%"), 
seq(0, 1, by = .25),expand = expansion(mult = c(0, 0))) +
geom_col(data = df, 
mapping= aes(x = c("Female"), y = female_perc[2]/2), 
fill = lightest_accent, width = .25) +
geom_col(data = df, 
mapping= aes(x = c("Female"), y = female_perc[1]/2), 
fill = dark, width = .15) +
coord_flip()

为了扩展Gregor Thomas的启发性答案,这里有一个如何调整数据并绘制数据的示例:

df %>%
pivot_longer(
-Covid,
values_to = "fraction",
names_to = c("sex", "type"),
names_sep = "_"
) %>%
ggplot(aes(x = sex, y = fraction, fill = Covid)) +
geom_col(position = "dodge")

在这里,pivot_longer获取嵌入原始data.frame列名中的性别信息,并将其作为变量提供给ggplot,这样您就可以通过编程访问它们,并使您的绘图对它们做出响应。

更新:

一个"整洁"的解决方案,对每个酒吧的美学进行更多的手动控制,以实现所需的外观:

df %>%
pivot_longer(
-Covid,
values_to = "fraction",
names_to = c("sex", "type"),
names_sep = "_"
) %>%
arrange(desc(Covid)) %>%
ggplot(aes(x = sex, y = fraction, group = Covid)) +
geom_col(position = "identity", aes(width = rep(c(0.25, 0.15), each = 2), fill = letters[1:4]), alpha = 1) +
scale_fill_manual(values = c(lightest_accent, light_accent, dark, lightest)) +
scale_y_continuous(limits = c(0, 1), breaks = seq(0, 1, by = .25),
labels = function(y) paste0(round(y*100,0),"%"), 
seq(0, 1, by = .25),expand = expansion(mult = c(0, 0))) + 
theme(legend.position = "none") +
coord_flip()

请注意,arrange调用按所需顺序绘制条形图,因此data.frame中最后的条形图将绘制在最后并位于顶部。widthfill必须手动设置以匹配所需的顺序。

ggplot使用您的数据帧。当您使用geom_col(data = df, ...)时,geom_col将尝试为df的每一行绘制一个geom。您明确设置了x = "Male"y male_perc[2]/2,并且这些单个值将被回收用于数据帧的每一行。

与此相同:

ggplot(data = data.frame(x = c(1, 2, 3, 4)) +
geom_line(aes(x = x, y = 1))

我给ggplot一个4行的数据帧。我告诉它y = 1,所以y1被回收并应用于所有4行。您的x = "Male"y = male_perc[2]/2将在所有2行数据中循环使用。

默认情况下,geom_col会将重叠的值叠加在一起。这就是数据翻倍的方式。

比除以2更好的是,您可以使用position = "identity",这样就不会堆叠任何东西。更好的是,将数据放在长格式中,并使用美学映射。

最新更新