#r #random #bioinformatics
Вопрос:
У меня есть текстовый файл, содержащий миллионы значений p (диапазон: 1-5e — 09, ($P)). Моя цель состоит в том, чтобы сгенерировать график Манхэттена в R, используя эти p-значения. Однако, поскольку подавляющее большинство значений p находятся в диапазоне 0,01-1, я хотел бы случайным образом обрезать, скажем, 95% значений p в этом диапазоне перед созданием графика (чтобы уменьшить размер выходного файла). До сих пор я использовал:
data <- read.table(<path_to_my_p-value_file>)
data <- subset(data,data$P<=0.01)
но эта команда удаляет все значения p, превышающие 0,01, что приводит к появлению неприглядного разрыва между осью x и оставшимися значениями p на графике Манхэттена. Есть ли способ обрезать большинство значений p в указанном диапазоне (вместо всех)?
Комментарии:
1. (1) При использовании
subset(data, ...)
нет причин использоватьdata$
в вызове , просто используйтеsubset(data, P <= 0.01)
. Это относится не ко всем функциям, ноsubset
и всеdplyr::
функции ценят «нестандартную оценку». (2) Было бы намного проще, если бы вы могли сгенерировать приемлемый образец набора данных (это не обязательно должны быть фактические значения p), чтобы продемонстрировать, с чего вы начинаете и что вы намереваетесь. Спасибо.
Ответ №1:
Здесь метод, который обнуляет 90% самых высоких 95% значений. Очевидно, что вы не хотели бы делать это на оригинале ваших данных, а скорее на копии, из которой вы затем удалили бы 0. Умножьте более высокие значения p (самые высокие 95% в этом примере) на случайную выборку из {,0,1} правильной длины с вероятностью 0,9 для 0 и 0,1 для 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 и 11 выше 0,05. Точное количество этих более высоких значений будет немного отличаться в зависимости от случайного начального значения и длины построенного вектора.
> 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». (Нет, я не ошибся в написании этого термина.)
Ответ №2:
Это кажется немного хакерским, но следующее может это сделать. В основном он сначала проверяет наличие условия (здесь, если 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")
Создано 2021-07-05 пакетом reprex (v2.0.0)