Хорошие методы для графиков плотности неотрицательных переменных в R?


36
plot(density(rexp(100))

Очевидно, что вся плотность слева от нуля представляет собой смещение.

Я хочу обобщить некоторые данные для статистиков, и я хочу избежать вопросов о том, почему неотрицательные данные имеют плотность слева от нуля. Графики для проверки рандомизации; Я хочу показать распределение переменных по группам лечения и контроля. Распределения часто экспоненциальные. Гистограммы хитры по разным причинам.

Быстрый поиск в Google дает мне работу статистиков по неотрицательным ядрам, например: это .

Но было ли что-нибудь реализовано в R? Из реализованных методов, являются ли какие-либо из них «лучшими» в некоторой степени для описательной статистики?

РЕДАКТИРОВАТЬ: даже если fromкоманда может решить мою текущую проблему, было бы неплохо знать, внедрил ли кто-нибудь ядра на основе литературы по неотрицательной оценке плотности


3
Не то, что вы спрашиваете, но я бы не стал применять оценку плотности ядра к чему-то, что должно быть экспоненциальным, особенно для представления не статистической аудитории. Я бы использовал график квантиль-квантиль и объяснил, что график должен быть прямым, если распределение было экспоненциальным.
Ник Кокс

6
plot(density(rexp(100), from=0))?
Стефан Лоран

4
Одна вещь, которую я иногда делал довольно успешно, - это получить kde на бревнах, а затем преобразовать оценку плотности (не забывая о якобиане). Другой возможностью было бы использовать оценку плотности лог-сплайна, настроенную так, чтобы она знала о границе.
Glen_b


1
Я обсуждал метод преобразования, упомянутый @Glen_b в stata-journal.com/sjpdf.html?articlenum=gr0003 (см. Стр.76-78). Нули можно было бы разместить, используя log (x + 1), а не log и модифицируя якобиан.
Ник Кокс

Ответы:


21

Одно из решений, заимствованное из подходов к краевому взвешиванию пространственной статистики, состоит в том, чтобы обрезать плотность слева в ноль, но увеличить вес данных, которые ближе всего к нулю. Идея состоит в том, что каждое значение «распространяется» на ядро ​​общей площади единицы с центром в x ; любая часть ядра, которая могла бы пролиться на отрицательную территорию, удаляется, и ядро ​​перенормируется в единичную область.ИксИкс

Например, с гауссовым ядром , перенормировочный весКчас(Y,Икс)знак равноехр(-12((Y-Икс)/час)2)/2π

вес(Икс)знак равно1/0К(Y,Икс)dYзнак равно11-ΦИкс,час(0)

где - кумулятивная функция распределения нормального изменения среднего значения x и стандартного отклонения h . Сравнимые формулы доступны для других ядер.ΦИксчас

000

фигура

0


Код R

densityФункция Rбудет жаловаться , что сумма весов не равен единице, так как он хочет , чтобы интеграл по всех действительных чисел равным единице, в то время как этот подход делает интеграл над положительными числами , равными единице. В качестве проверки последний интеграл оценивается как сумма Римана.

set.seed(17)
x <- rexp(1000)
#
# Compute a bandwidth.
#
h <- density(x, kernel="gaussian")$bw # $
#
# Compute edge weights.
#
w <- 1 / pnorm(0, mean=x, sd=h, lower.tail=FALSE)
#
# The truncated weighted density is what we want.
#
d <- density(x, bw=h, kernel="gaussian", weights=w / length(x))
d$y[d$x < 0] <- 0
#
# Check: the integral ought to be close to 1:
#
sum(d$y * diff(d$x)[1])
#
# Plot the two density estimates.
#
par(mfrow=c(1,1))
plot(d, type="n", main="Default and truncated densities", xlim=c(-1, 5))
polygon(density(x, kernel="gaussian", bw=h), col="#6060ff80", border=NA)
polygon(d, col="#ff606080", border=NA)
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)

21

Альтернативой является подход Куперберга и его коллег, основанный на оценке плотности с использованием сплайнов для аппроксимации логарифмической плотности данных. Я покажу пример, используя данные из ответа @ whuber, который позволит сравнить подходы.

set.seed(17)
x <- rexp(1000)

Для этого вам понадобится пакет logspline ; установите его, если это не так:

install.packages("logspline")

Загрузите пакет и оцените плотность, используя logspline()функцию:

require("logspline")
m <- logspline(x)

Далее я предполагаю, что объект dиз ответа @ whuber присутствует в рабочей области.

plot(d, type="n", main="Default, truncated, and logspline densities", 
     xlim=c(-1, 5), ylim = c(0, 1))
polygon(density(x, kernel="gaussian", bw=h), col="#6060ff80", border=NA)
polygon(d, col="#ff606080", border=NA)
plot(m, add = TRUE, col = "red", lwd = 3, xlim = c(-0.001, max(x)))
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)
rug(x, side = 3)

Полученный график показан ниже, а плотность сплайн-логарифмов показана красной линией

Плотность по умолчанию, усеченная и логсплайн

Кроме того, поддержка плотности может быть указана с помощью аргументов lboundи ubound. Если мы хотим предположить, что плотность равна 0 слева от 0, и в 0 есть разрыв, мы могли бы использовать lbound = 0в вызове logspline(), например,

m2 <- logspline(x, lbound = 0)

Выводит следующую оценку плотности (показанную здесь с исходным mподбором лог-сплайна, так как предыдущий рисунок уже был занят).

plot.new()
plot.window(xlim = c(-1, max(x)), ylim = c(0, 1.2))
title(main = "Logspline densities with & without a lower bound",
      ylab = "Density", xlab = "x")
plot(m,  col = "red",  xlim = c(0, max(x)), lwd = 3, add = TRUE)
plot(m2, col = "blue", xlim = c(0, max(x)), lwd = 2, add = TRUE)
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)
rug(x, side = 3)
axis(1)
axis(2)
box()

Получившийся сюжет показан ниже

Сравнение оценок плотности logspline с и без нижней границы на поддержку

xИксзнак равно0x


1
01

@whuber Хороший вопрос. Я только недавно столкнулся с этим подходом. Я подозреваю, что хороший вопрос, который нужно здесь задать, заключается в том, что укороченные методы и методы logspline являются всего лишь оценками истинной плотности. Являются ли различия в соответствии статистически значимыми? Я не уверен точно, почему это так хорошо в ноль, хотя. Я был бы признателен, если бы знал почему.
Восстановить Монику - Дж. Симпсон

@GavinSimpson, спасибо за этот хороший ответ. Можете ли вы воспроизвести последний сюжет с последней версией logspline? Для меня плотность как ограниченной, так и неограниченной версии сводится к нулю при x = 0.
чел

4

Чтобы сравнить распределения по группам (которые вы называете целью в одном из ваших комментариев), почему бы не сделать что-то попроще? Графики параллельных блоков работают хорошо, если N большое; графики с параллельными полосами работают, если N мало (и оба хорошо показывают выбросы, что, по вашим словам, является проблемой в ваших данных).


1
Да, спасибо, это работает. Но мне нравятся графики плотности. Они показывают больше о данных, чем коробочные графики. Думаю, я немного удивлен, что, кажется, ничего не было реализовано. Может быть, я когда-нибудь сам осуществлю одну из этих вещей. Люди, вероятно, найдут это полезным.
generic_user

1
Мне тоже нравятся графики плотности; но вы должны учитывать свою аудиторию.
Питер Флом - Восстановить Монику

1
Должен согласиться с @PeterFlom по этому вопросу. Не становитесь слишком сложным, если ваша аудитория не обладает статистическими знаниями. Вы также можете сделать сравнительные / параллельные коробочные графики с наложением графиков бабочек сверху. Таким образом, сводная таблица отображается как все данные.
doug

Предложение о том, что разные люди по-разному понимают совокупные графики, безусловно, верно. Несмотря на понимание того, что такое график плотности (и понимание того, что это не вероятность), я не понимаю, что такое «параллельный блокпост». Он предлагает параллельный график координат, но я подозреваю, что это не правильно.
DWin

2

В качестве комментариев Стефана вы можете использовать from = 0и, кроме того, вы можете представить свои значения под кривой плотности с помощьюrug (x)


4
Поправьте меня, если я ошибаюсь, но from=0выглядит так, как будто он просто подавляет построение графиков для значений ниже 0; это не корректирует вычисления для того факта, что часть распределения была размазана ниже 0.
Ник Кокс

1
Это правильно. Использование fromкоманды дает график, который выглядит так, как будто он имеет пик справа от нуля. Но если вы посмотрите на гистограммы с постоянно меньшими ячейками, многие данные покажут пик AT нулевым. Это fromпросто графический трюк.
generic_user

@NickCox Я не уверен, но я не думаю, from=0что что-то подавляет. Он просто начинает «сетку» с нуля.
Стефан Лоран

Разница заключается в том, является ли оценочная плотность ненулевой для отрицательных значений, а не на графике или нет. Исследователи могут решить не беспокоиться об этом, если все, что они хотят, это визуализация.
Ник Кокс

@NickCox Команда density(rexp(100), from=0)не имеет ничего общего с графикой
Стефан Лоран
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.