如何trim R中特定范围内的数据点百分比

How to trim a percentage of data points within a specific range in R

我有一个包含数百万个 p 值(范围:1 - 5e-09,$P)的文本文件。我的目标是使用这些 p 值在 R 中生成曼哈顿图。但是,由于绝大多数 p 值都在 0.01-1 范围内,我想在生成绘图之前随机 trim 说,95% 的 p 值在这个范围内(以减少输出文件大小)。到目前为止,我一直在使用:

data <- read.table(<path_to_my_p-value_file>)
data <- subset(data,data$P<=0.01)

但此命令会删除 所有 个大于 0.01 的 p 值,这会导致曼哈顿图中 x 轴和其余 p 值之间存在难看的间隙。有没有办法在指定范围内 trim 大多数 p 值(而不是全部)?

感觉有点hacky,但是下面可以做到。基本上,它首先检查一个条件(这里如果 x > 0),然后替换为缺少基于 runif()(这里 .95)的值的百分比。之后,您可以删除缺少值的行。

虽然应该有更好的方法来达到预期的结果...

df2 <- df %>% mutate(
  x = if_else(condition = x > 0,
              true = if_else(runif(length(x))<.95, NA_real_, x),
              false = x
  )
)

代表

library(dplyr)

set.seed(42)
n <- 300
df <- data.frame(
  x = rnorm(n), 
  y = rnorm(n)
)

df2 <- df %>% mutate(
  x = if_else(condition = x > 0,
              true = if_else(runif(length(x))<.95, NA_real_, x),
              false = x
  )
)
plot(df, pch = 3)
points(df2, col = "red")

reprex package (v2.0.0)

于 2021-07-05 创建

这是一种方法,可以将最高 95% 的值中的 90% 归零。显然,您不希望对原始数据执行此操作,而是希望对副本执行此操作,然后从中删除 0。将较高的 p 值(本例中最高 95%)乘以来自 {,0,1} 的随机抽样,该抽样具有正确的长度,0 的概率为 0.9,1

的概率为 0.1
 set.seed(123)
 dx <- data.frame(x=runif(100))
 dx$sel <- dx$x < 0.05    #Should "select" the lowest 5%, leave them alone
 dx$x[!dx$sel] <- dx$x[!dx$sel]*   # only work on the higher ones
                       sample(c(0,1),size=sum(!dx$sel), replace=TRUE, prob=c(.9,.1))

获得低于 0.05 的五个值和高于 0.05 的 11 个值。这些较高值的确切数量会有所不同,具体取决于随机种子和构造向量的长度。

> table(dx$x)

                   0 0.000624773325398564   0.0246136845089495   0.0420595335308462 
                  84                    1                    1                    1 
  0.0455564993899316   0.0458311666734517   0.0935949867125601    0.102924682665616 
                   1                    1                    1                    1 
   0.320373242488131    0.414546335814521    0.453334156190977    0.511505459900945 
                   1                    1                    1                    1 
    0.59414202044718    0.656758127966896    0.883017404004931    0.892419044394046 
                   1                    1                    1                    1 
   0.954503649147227 

您还可以查看执行“winsorizing”的函数使用的代码。 (不,我没有拼错那个词。)