叠加 geom_point 到 geom_bar。如何对齐点和条?

Overlay geom_point to geom_bar. How to align the points and bars?

我已经尝试了足够长的时间,我只需要问一下...这看起来很基础,之前可能有人问过,但我找不到任何适用于我的特定情况的 post .

非常简单,我有 2 个数据框,它们具有相同的分组变量但我想绘制不同的数据,一个作为条形,另一个作为顶部的点。

我在这个例子中使用 mtcars。我有我的 ID 变量作为汽车模型,然后我使用两个分组变量 carbcyl,它们都在我的数据框中。

一个数据框具有每个 carbcylmax disp 值,因此它更短(我将所有 carb-[= 的缺失值填充为 0 15=]组合);我想把它绘制成条形图。

另一个数据框每个模型都有单独的 disp 值,我想将其作为点绘制在顶部。

这是我的方法,但是结果图确实是错误的,需要在那里调整颜色和点的位置...理想情况下我希望所有的点都是黑色的,但我似乎只将它们分开如果我这样做 color,请分组。对于定位,它进入函数内部,因此应该适用于数据框分组变量中的任意数量的级别。

mtcars$model <- rownames(mtcars)
mtcars$cyl <- as.factor(as.character(mtcars$cyl))
mtcars$carb <- as.factor(as.character(mtcars$carb))

mydf1 <- as.data.frame(data.table::data.table(mtcars)[, list(max=max(disp)), by=list(cyl=cyl, carb=carb)])

mydf2 <- mtcars[,c(2,3,11,12)]
zerodf <- expand.grid(cyl=unique(mtcars$cyl), carb=unique(mtcars$carb))

mydf1 <- merge(mydf1, zerodf, all=TRUE)
mydf1$max[which(is.na(mydf1$max))] <- 0

P <- ggplot2::ggplot(data=NULL) +
  ggplot2::geom_bar(data=mydf1, ggplot2::aes(carb, max, fill=cyl), position="dodge", stat="identity") +
  ggplot2::scale_fill_manual(values=c("blue","red","grey"))

P <- P + ggplot2::geom_point(data=mydf2, ggplot2::aes(carb, disp, color=cyl), position=ggplot2::position_dodge(width=0.5), shape=3, size=5, show.legend=FALSE)

简单的问题是点的着色。要获得黑点,只需将 cyl 映射到 geom_point 图层中的 group 美学。棘手的部分是定位。要正确定位点,您必须填写 mydf2 以包括 cylcarb 的所有组合,就像您已经为 mydf1 所做的那样。为此我使用tidyr::complete。试试这个:

library(ggplot2)

mtcars$model <- rownames(mtcars)
#head(mtcars)

mtcars$cyl <- as.factor(as.character(mtcars$cyl))
mtcars$carb <- as.factor(as.character(mtcars$carb))
#summary(mtcars)
mydf1 <- as.data.frame(data.table::data.table(mtcars)[, list(max=max(disp)), by=list(cyl=cyl, carb=carb)])

mydf2 <- mtcars[,c(2,3,11,12)]

zerodf <- expand.grid(cyl=unique(mtcars$cyl), carb=unique(mtcars$carb))
mydf1 <- merge(mydf1, zerodf, all=TRUE)
mydf1$max[which(is.na(mydf1$max))] <- 0

mydf2 <- tidyr::complete(mydf2, carb, cyl)

ggplot(data = NULL, aes(group = cyl)) +
  geom_bar(data=mydf1, aes(carb, max, fill=cyl), position="dodge", stat="identity") +
  scale_fill_manual(values=c("blue","red","grey")) +
  geom_point(data=mydf2, aes(carb, disp, group=cyl), position = position_dodge(width = 0.9), shape=3, size=5, show.legend=FALSE)
#> Warning: Removed 9 rows containing missing values (geom_point).