【问题标题】:Summarising data before plotting with geom_tile() renders different results在使用 geom_tile() 绘图之前汇总数据会呈现不同的结果
【发布时间】:2021-07-01 15:25:15
【问题描述】:

我注意到,当使用ggplot2geom_tile() 进行绘图时,在绘图之前汇总数据会呈现与未预先汇总时完全不同的结果。我不明白为什么。

对于具有三列 year(字符)、state(字符)和 profit(数字)的数据框,请考虑以下示例:

# Plot straight away 

data %>% 
ggplot(aes(x=year, y=state)) + geom_tile(aes(fill=profit)) 

# Summarise before plotting

data %>% group_by(year, state) %>% summarize(profit_mean = mean(profit)) %>%
ungroup() %>% 
ggplot(aes(x=year, y=state)) + geom_tile(aes(fill=profit_mean))

这两个示例呈现了两个不同的平铺图 - 值完全不同。我认为这两种绘图方法是类似的,ggplot2 会自动取平均值 - 不是这样吗?

我尝试在较小的数据子集上重现此错误,但没有出现。这里会发生什么?

【问题讨论】:

  • 因为第二个是mean 值,而第一个是使用stat_identity 列的原始值
  • 谢谢,请问,如何使用原始值?是要一笔钱还是什么意思?
  • 它使用原始数据。您可以查看我显示的链接。另外,在?stat_identity -The identity statistic leaves the data unchanged.的文档中
  • 默认(可能)是过度绘制数据,因此一行最终位于顶部,这就是您看到的值。就像您绘制 10 个不同颜色但 x,y 坐标相同的点一样 - 一个点最终位于顶部。

标签: r ggplot2 dplyr


【解决方案1】:

OP,这是一个非常有趣的问题。

首先,让我们解决这个问题。很明显,绘制数据摘要正在绘制的只是:摘要。您正在通过平均值进行汇总,因此绘制的内容等于每个图块值的平均值。

这里的实际问题是:如果您有一个数据集包含每个图块多个值,那么绘制“未汇总”数据集的结果是什么?

用户@akrun 是正确的:用于geom_tile 的默认statstat="identity",但可能不清楚这究竟是什么意思。它说它“保持数据不变”......但不清楚这意味着什么。

说明性示例数据集

出于演示的目的,我将创建一个说明性数据集,它将非常清楚地回答问题。我正在创建两个单独的数据集 df1df2,每个数据集都包含 4 个“图块”数据。这些之间的区别在于图块的值本身是不同的。为了更清晰,我在每个图块上添加了文本标签。

library(ggplot2)
library(cowplot)

df1 <- data.frame(
  x=rep(paste("Test",1:2), 2),
  y=rep(c("A", "B"), each=2),
  value=c(5,15,20,25)
)

df2 <- data.frame(
  x=rep(paste("Test",1:2), 2),
  y=rep(c("A", "B"), each=2),
  value=c(10,5,25,15)
)

tile1 <- ggplot(df1, aes(x,y, fill=value, label=value)) +
  geom_tile() + geom_text() + labs(title="df1")

tile2 <- ggplot(df2, aes(x,y, fill=value, label=value)) +
  geom_tile() + geom_text() + labs(title="df2")

plot_grid(tile1, tile2)

绘制组合数据框

df1df2 的每个数据框每个图块仅包含一个值,因此为了了解当每个图块具有多个值时情况如何变化,我们需要将它们组合成一个,以便每个图块tile 将包含 2 个值。在这个例子中,我们将通过两种方式组合它们:首先是df1,然后是df2,另一种是先df2,然后是df1

df12 <- rbind(df1, df2)
df21 <- rbind(df2, df1)

现在,如果我们像以前一样绘制每个图并进行比较,OP 发布的差异的原因应该很明显。我将每个原始数据集的每个图块的值都包括在内,以使事情变得超级清晰。

tile12 <- ggplot(df12, aes(x,y, fill=value, label=value)) +
  geom_tile() + labs(title="df1, then df2") +
  geom_text(data=df1, aes(label=paste("df1:",value)), nudge_y=0.1) +
  geom_text(data=df2, aes(label=paste("df2:",value)), nudge_y=-0.1)

tile21 <- ggplot(df21, aes(x,y, fill=value, label=value)) +
  geom_tile() + labs(title="df2, then df1") +
  geom_text(data=df1, aes(label=paste("df1:",value)), nudge_y=0.1) +
  geom_text(data=df2, aes(label=paste("df2:",value)), nudge_y=-0.1)

plot_grid(tile12, tile21)

请注意,图例颜色条的值不会改变,所以它不会做加法。另外,既然我们知道它是stat="identity",我们知道这不应该是这样。当我们使用包含来自df1 的第一个观测值,然后是来自df2 的观测值的数据集时,绘制的值是来自df2 的值。当我们使用包含首先来自df2,然后来自df1 的观测值的数据集时,绘制的值是来自df1 的值。

鉴于这条信息,可以清楚地看出,当使用stat="identity"(默认参数)时,geom_tile() 中显示的值对应于数据框中表示的特定图块的最后一次观察 >.

所以,这就是为什么你的情节看起来很奇怪的原因。既可以事先总结,也可以使用stat_summary(geom="tile"...ggplot内一次性完成转换。

【讨论】:

  • 非常感谢!!这真的让我明白那里发生了什么。
  • 它的工作方式对我来说并不明显(我敢打赌这对任何人来说都不明显),但你的问题激起了我的好奇心。我很高兴有机会对此进行研究,希望对其他人有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
相关资源
最近更新 更多