Имитация значений с пользовательской плотностью

У меня есть теоретический вопрос и вопрос по кодированию, связанный с плотностью и симуляцией значений.

Я создаю пользовательские плотности с помощью командыdensity(x). Однако я надеюсь сгенерировать 1000-10000 смоделированных значений из этой плотности. Общая цель состоит в том, чтобы взять две плотности, построенные по форме плотности (x $ y), запустить симуляции и сказать, что эта плотность A больше, чем плотность B x% времени. Я бы просто взял каждое смоделированное значение и посмотрел, какое из них выше, и код, чтобы подсчитать, во сколько раз A выше, чем B.

Есть ли способ сделать это? Или есть какой-то способ сделать что-то подобное с этими плотностями? Спасибо!


person BaseballR    schedule 18.09.2013    source источник
comment
Да, проблема в том, что я строю гладкую плотность, основываясь только на 86 сэмплах, но у меня есть основания полагать, что она может попасть в любое место внутри плотности, поэтому я надеюсь смоделировать в пределах этой плотности, какие-нибудь мысли?   -  person BaseballR    schedule 19.09.2013


Ответы (2)


Функция sample может брать средние точки интервалов плотности выборки, а затем использовать плотности в качестве пробных аргументов.

mysamp <- sample(x= dens$x, size=1000  , prob=dens$y, repl=TRUE)

Недостаток этого в том, что вам может понадобиться колебание результата, чтобы избежать большого количества дубликатов.

 mysamp <- jitter(mysamp)

Другой способ — использовать approxfun и ecdf. Возможно, вам придется инвертировать функцию (обратная роль x и y), чтобы использовать вход runif(1000) в результат. Я почти уверен, что в SO есть проработанные примеры этого, и я почти уверен, что я один из многих, кто в прошлом публиковал такой код в R-help. (Если ваши поиски не дали результатов, опубликуйте стратегии поиска, и другие могут попытаться их улучшить.)

person IRTFM    schedule 18.09.2013
comment
чтобы избежать предупреждения, используйте prob=dens$y/sum(dens$y) - person Ferdinand.kraft; 19.09.2013
comment
Это потрясающе, именно то, что я искал! - person BaseballR; 19.09.2013

Следуя совету @DWin по инвертированию ecdf, вот как реализовать такой подход, используя сплайн для соответствия инвертированной ступенчатой ​​функции:

Данный

z <- c(rnorm(40), runif(40))
plot(density(z))

введите здесь описание изображения

Определять

spl <- with(environment(ecdf(z)), splinefun(y, x))

sampler <- function(n)spl(runif(n))

Теперь вы можете вызвать sampler() с нужным вам размером:

plot(density(sampler(1000)))

введите здесь описание изображения

Последнее замечание: это никогда не будет генерировать значения за пределами диапазона исходных данных, но дубликаты будут крайне редки:

> anyDuplicated(sampler(1e4))
[1] 0
person Ferdinand.kraft    schedule 18.09.2013