【问题标题】:Remove unused factor levels from a ggplot bar plot从 ggplot 条形图中删除未使用的因子水平
【发布时间】:2012-07-09 07:50:38
【问题描述】:

我想做与this question相反的事情,和this question做相反的事情,虽然那是关于传说,而不是情节本身。

其他 SO 问题似乎是在询问如何保持未使用的因子水平。我实际上希望我的删除。我有几个名称变量和几个变量属性列(宽格式),用于创建大量条形图。这是一个可重现的示例:

library(ggplot2)
df <- data.frame(name=c("A","B","C"), var1=c(1,NA,2),var2=c(3,4,5))
ggplot(df, aes(x=name,y=var1)) + geom_bar()

我明白了:

我只希望在我的条形图中显示具有相应 varn 的名称(例如,B 不会有空白区域)。

如果我可以简单地更改我的输出文件名和y=var 位,重用基本绘图代码将非常容易。如果可能的话,我不想仅仅为了在每个绘图的结果上使用 droplevels 而对我的数据框进行子集化!


根据na.omit() 建议更新

考虑修改后的数据集:

library(ggplot2)
df <- data.frame(name=c("A","B","C"), var1=c(1,NA,2),var2=c(3,4,5), var3=c(NA,6,7))
ggplot(df, aes(x=name,y=var1)) + geom_bar()

我需要使用 na.omit() 来绘制 var1 因为存在 NA。但由于 na.omit 确保 所有列 都存在值,因此该图也会删除 A,因为它在 var3 中有一个 NA。这更类似于我的数据。我总共有 15 条回复,其中充斥着 NA。我只想删除没有为 current 绘制的 y 向量值的因子水平,而不是在整个数据帧中的 any 向量中具有 NA。

【问题讨论】:

  • 为什么你需要一个数据框开始,而你实际上只是绘制一行?如果您没有数据框(更确切地说,只有一个列表/向量),您可以删除 NA 字段)。
  • @TiloWiklund:我是 R 新手,所以请随意提出替代方案。我正在针对一系列绘图的许多不同数据列绘制一列名称。有些列不完整,有些则不完整。不完整的与上述类似,并且留下了我不想要的空白,因为我只需要比较实际具有与特定测量响应相关联的数据的变量。这有意义吗?
  • 您也可以通过仅在该列上设置条件来简单地删除行:ggplot(df[!is.na(df$var1),], aes(x=name,y=var1)) + geom_bar()
  • @joran:这似乎与下面的 Tilo 解决方案非常相似,尽管比传递两个向量名称要简单一些。不管省略 na 的调整如何,我想真正的教训是没有办法从 ggplot 自动执行此操作。
  • @TiloWiklund ggplot() 需要一个数据框作为它的第一个参数。无论如何,他不是画了两行吗,一个是因子(name),另一个是数字(var1)? Hendy 需要传递这两个变量,否则ggplot() 怎么知道将值绘制为两个条形而不是数据的数字向量?

标签: r plot ggplot2 factors


【解决方案1】:

一个简单的选择是在您的数据框df 上使用na.omit() 来删除带有NA 的那些行

ggplot(na.omit(df), aes(x=name,y=var1)) + geom_bar()

鉴于您的更新,以下

ggplot(df[!is.na(df$var1), ], aes(x=name,y=var1)) + geom_bar()

工作正常,只考虑Var1 中的NA。鉴于您只绘制nameVar,请将na.omit() 应用于仅包含这些变量的数据框

ggplot(na.omit(df[, c("name", "var1")]), aes(x=name,y=var1)) + geom_bar()

【讨论】:

  • 这很棒而且非常简单。我的实际数据集必须缺少许多列中的一个或多个值,因为应用 na.omit 会给我留下一个没有行的数据框......还有其他建议吗?
  • 最初知道这一点会很有帮助。查看我更新的答案。
  • 我也想说明这一点。不知道会出现什么解决方案,我没有意识到这将是一个问题。老实说,我希望有一个 ggplot 选项来丢弃东西。鉴于人们希望在链接的问题中保留未使用的级别并且能够指定drop=FALSE,我有点想知道为什么drop=T 不会完全按照我的意愿去做!感谢您提供更新的答案。
  • @Hendy 级别 B 在您的示例中未使用。它非常常用,因为它存在于数据中。就 R 而言,NA 与任何其他值一样有效的数据点。真正未使用的级别是A &lt;- factor(c("a","c"), levels = c("a","b","c")) 中的B。在A 中,级别b 不存在于数据中。
  • 当然,从技术上讲,我想。从我的角度来看,我有原型和大量测量的测试结果。原型B和测试方法var1的交集处没有数据。我的数据框由一列原型名称和一列测试数据组成。宽格式。 “真正未使用的关卡”只有在很长的时间内才有可能,对吧?
【解决方案2】:

请注意,在绘图时,您仅使用数据框的两列,这意味着您可以使用相关列 x[,c("name", "var1")] 应用 na.omit 来删除不需要的行,而不是传递整个 data.frame (正如 Gavin Simpson 建议的那样)na.omit(x[,c("name", "var1")]),然后绘制此数据。

我的 R/ggplot 很生锈,我意识到可能有更清洁的方法来实现这一点。

【讨论】:

  • 没有意识到我可以在 ggplot 中做到这一点,但现在看起来很明显。这绝对有效。如果有一个等价于drop=Tscale="free",那就太好了,因为我必须以这种方式调整我的所有绘图功能。应该不会太糟糕,我将只使用dat[, c(1,n)],这样我就可以轻松地遍历每一个。谢谢!
【解决方案3】:

自从最初提出这个问题以来已经过去了很长时间。如果我在 2021 年处理这个问题,我会使用类似的东西:

library(ggplot2)
library(tidyr)
df <- data.frame(name=c("A","B","C"), var1=c(1,NA,2),var2=c(3,4,5))

df %>% 
  drop_na(var1) %>% 
  ggplot(aes(name, var1)) +
  geom_col()

reprex package (v2.0.1) 于 2021-12-03 创建

【讨论】:

  • 这太棒了!我认为有很多这样的问题。我刚刚做了与另一个问题类似的事情,与dplyr 相比,现在所有的答案都显得繁琐而乏味。感谢您抽出宝贵时间modernize() :)
猜你喜欢
  • 2016-08-08
  • 2019-11-23
  • 1970-01-01
  • 2022-01-28
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
相关资源
最近更新 更多