首页 > 解决方案 > 根据密度对数据框进行子集

问题描述

我正在寻找一个允许根据双变量观察的密度对数据框进行子集化的函数。例如:

ggplot(iris, aes(x = Petal.Length, y = Sepal.Width, color = Species)) + 
  stat_density2d(geom = 'polygon', aes(fill = ..level..), n = 8) + 
  geom_point()

在这里,我只想显示基于物种内点密度的异常点(即仅显示来自 setosa 的 3 个点和来自位于等高线之外的弗吉尼亚州的 4 个点)。

标签: rggplot2dplyr

解决方案


我的方法有点复杂,所以请耐心等待,我将在下面解释:

library(data.table)
dt <- as.data.table(iris)[, .(Petal.Length, Sepal.Width, Species)]
dt[, sample := .I]
dt <- melt(dt, id.vars = c("Species", "sample"))
dt[, c("meanval", "sdval") := .(mean(value), sd(value)), .(Species, variable)]
dt[abs({value - meanval} / sdval) > 2, outlier := TRUE]
dt[, anyOutliers := sum(outlier, na.rm = T), sample]
dt[anyOutliers != 0, outlier := TRUE]
dt <- dcast(
  dt[, .(Species, variable, value, outlier, sample)],
  sample + outlier + Species ~ variable,
  value.var = "value"
)

首先,我们指定dt为数据集并仅保留我们计划绘制的列。接下来,我们分配一个虚拟列,这对于这个特定数据集稍后区分行很重要。然后我们melt()为权宜之计的数据集。然后,对于每个物种,我们计算每个值的平均值和标准差。这使我们能够在下面的行中定义异常值(您可以> 2在此处更改以影响要使用的 SD 数量)。

然后,对于每朵花,我们会在我们选择的任何指标(在本例中为 petal.length 和 sepal.width)中查找它是否是异常值。如果是这样,整朵花就会被标记为异常值。然后,我们将表格恢复为原始形式,只是现在有一个异常值列显示花是否是任何输出指标中的异常值。

我不会去绘制这些,因为你可以自己弄清楚你想如何做到这一点,但这应该给出一个大致的方向。希望有帮助。


推荐阅读