解释 ggplot2 的警告信息:“已删除包含缺失值的 k 行”

119

我在使用ggplot生成图表时遇到了这个警告。

在网上搜索一段时间后,许多人建议我的数据库包含空值或缺失的数据,但事实并非如此。

在这个问题中,被接受的答案说:

警告意味着某些元素被删除,因为它们超出指定范围

我想知道这个范围到底是什么,以及如何手动增加这个范围,以避免所有警告?


7
该问题的“y”轴有一个限制。由于函数“ylim(0,0.12)”限制了其数值范围在0到0.12之间,因此数值受到限制。 - LyzandeR
1
一个可重现的例子会有助于回答这个问题。@LyzandeR 似乎正在正确的方向上前进。 - vpipkt
我也注意到,即使只是在geom_point()图中添加“jitter”,有时也会将意外的数据点排除在范围之外并出现此错误。 - RichardBJ
7个回答

114

你看到的行为是由于ggplot2处理超出图表轴范围的数据的方式所导致的。 scale_y_continuous(或等效地,ylim)在计算统计数据、摘要或回归线时排除了图表区域外的值。coord_cartesian包括所有这些计算中的值,无论它们是否可见于图表区域。以下是一些示例:

library(ggplot2)

# Set one point to a large hp value
d = mtcars
d$hp[d$hp==max(d$hp)] = 1000

这张图中所有的点都是可见的:

ggplot(d, aes(mpg, hp)) + 
  geom_point() +
  geom_smooth(method="lm") +
  labs(title="All points are visible; no warnings")
#> `geom_smooth()` using formula 'y ~ x'

下图中,一个hp值为1000的点在y轴范围之外。由于我们使用了scale_y_continuous来设置y轴范围,因此该点不包含在ggplot计算的任何其他统计或摘要信息中,例如由geom_smooth计算的线性回归线。 ggplot还会警告有关被排除点的信息。

ggplot(d, aes(mpg, hp)) + 
  geom_point() +
  scale_y_continuous(limits=c(0,300)) +  # Change this to limits=c(0,1000) and the warning disappears
  geom_smooth(method="lm") +
  labs(title="scale_y_continuous: excluded point is not used for regression line")
#> `geom_smooth()` using formula 'y ~ x'
#> Warning: Removed 1 rows containing non-finite values (stat_smooth).
#> Warning: Removed 1 rows containing missing values (geom_point).

下图中,hp值为1000的数据点仍然超出了纵坐标范围。不过,由于我们使用了coord_cartesian,因此ggplot计算的任何统计量或摘要信息,例如线性回归线,都会将该点包括在内。

如果您比较这张图和上一张图,您会发现第二张图中的线性回归线具有更陡峭的斜率和更宽的置信区间,因为在计算回归线时包含了hp=1000的数据点,即使它在图中不可见。

ggplot(d, aes(mpg, hp)) + 
  geom_point() +
  coord_cartesian(ylim=c(0,300)) +
  geom_smooth(method="lm") +
  labs(title="coord_cartesian: excluded point is still used for regression line")
#> `geom_smooth()` using formula 'y ~ x'


22

仅为完成eipi10所给答案而言。

我面临同样的问题,没有使用scale_y_continuouscoord_cartesian

冲突来自于x轴,我定义了limits = c(1, 30)。如果你想要“dodge”你的条形图,似乎这种限制不提供足够的空间,因此R仍然会抛出错误

已删除8行包含缺失值的数据(geom_bar)

调整x轴的极限到limits = c(0, 31)解决了这个问题。

总之,即使您没有对y轴设置限制,请检查x轴的行为以确保您有足够的空间。


1
这太容易被忽略了。同一个人再次在一段时间后犯了相同的错误…叹气*谢谢! - Saren Tasciyan

3
我知道这个问题已经有了答案,但这是另一个可能的解决方案。由于您没有提供示例代码,我无法确定。
如果您只想摆脱它,那意味着您对输出满意。然后您可以尝试以下操作:
na.rm=TRUE添加到geom_something中,例如:geom_line(..., na.rm=TRUE ) 这明确告诉geom_line(和geom_path)可以删除NA值。
分析警告信息:
警告:已删除k行包含缺失值(geom_path)
这主要告诉您3件事:
1. geom_path由另一个geom_something调用,该geom_something触发警告。 2. 它已经删除了k行。因此,如果输出符合要求,则需要删除这些行。 3. 移除的原因是某些值缺失(NA)。
警告没有告诉您为什么这些行具有缺失(NA)值,只有您自己才知道。
通常的原因是将比例限制设置为scale_x_datetimescale_y_continuous
这是有道理的,因为绘制(X,Y)对需要不是NA。
当您将X比例设置为较大的值而没有Y时,或者您的Y数据为NA时,您会得到其中一个NA的(X,Y)点。
您可能出于不同的原因而要设置更大的比例,但ggplot始终会发现没有关联的Y值,最好发出警告而不是错误。
祝您拥有愉快的一天。

2

另一个重要的变体是2019年开发的直方图

计算进行了更新,包括一些内容 - 如果我过于简化请原谅 -
比如根据您的分bin轴上的limit=()规范创建bins,
如果这个范围比您的数据宽,

  • 它会创建频率为0的条柱
  • 对于这些条柱会显示同样的警告

– 这是一个与修剪数据完全不同但具有相同信息的问题。

ggplot开发者在github上建议以几种不同的方式处理这个问题, https://github.com/tidyverse/ggplot2/issues/3265
https://github.com/tidyverse/ggplot2/issues/4083

1a. 如果在轴声明中使用limit=(),将您的limit=()精确设置为条柱的范围,即使轴刻度较宽

或者1b. 在有问题的轴声明中添加选项oob = scales::oob_keep 或者2. 如果使用xlimylim,请将其包裹在coord_cartesian()

1
选项1b应为scales::oob_keep。 示例: + scale_x_continuous(limits = c(0, 300), oob = scales::oob_keep) - HBat
好决定 - 在源文件中提到,但是我复制了错误的一个 - Mike M

1
即使你的数据在指定的范围内(例如c(0, 335)),添加geom_jitter()语句也可能会将一些点推出这些限制,从而产生相同的错误信息。
library(ggplot2)

range(mtcars$hp)
#> [1]  52 335

# No jitter -- no error message
ggplot(mtcars, aes(mpg, hp)) + 
    geom_point() +
    scale_y_continuous(limits=c(0,335))


# Jitter is too large -- this generates the error message
ggplot(mtcars, aes(mpg, hp)) + 
    geom_point() +
    geom_jitter(position = position_jitter(w = 0.2, h = 0.2)) +
    scale_y_continuous(limits=c(0,335))
#> Warning: Removed 1 rows containing missing values (geom_point).

本文创建于2020年8月24日,使用reprex package (v0.3.0)


0

另一个原因是存在NA值。 假设你的数组名称为arr,你可以通过以下方式简单地检查数组中是否有任何NA值:

any(is.na(arr))

如果答案是TRUE,那么你需要像下面这样删除NA:
arr = arr[-which(is.na(arr)]

即使没有 any(is.na(arr)),您也可以直接运行上述命令,R 将删除可能存在的任何 NA。


0

我也遇到了这个问题,但是在我想要避免额外的错误信息而保持所提供范围的情况下。另一个选项是在设置范围之前对数据进行子集处理,这样可以保持范围,而不触发警告。

library(ggplot2)

range(mtcars$hp)
#> [1]  52 335

# Setting limits with scale_y_continous (or ylim) and subsetting accordingly
## avoid warning messages about removing data
ggplot(data= subset(mtcars, hp<=300 & hp >= 100), aes(mpg, hp)) + 
  geom_point() +
  scale_y_continuous(limits=c(100,300))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接