Как моделировать данные и визуализировать в одной функции R - PullRequest
1 голос
/ 08 мая 2020

Я использую replicate для моделирования распределений в R и визуализации того, как они меняются с разными параметрами (например, rbinom(100,1,0.5) по сравнению с rbinom(100,1,0.01)).

Я хотел бы сделать все это в рамках одной функции, которая 1. моделирует реплики, 2. устанавливает размеры и параметры построения, и 3. проходит через кривые плотности и dr aws.

В отдельных частях этот код работает без проблем:

n <- 100
d <- as.data.frame(
    replicate(n, 
              expr = rbinom(n, 1, 0.5), 
              simplify = F)
)
colnames(d) <- 1:n
plot( NULL, xlim = c( min(d)-0.5, max(d)+0.5), ylim = c(0,2)) 
for(i in 1:n) lines( density( d[,i]) )

Но внутри функции возвращается только одна кривая плотности:

plotcurves <- function(n, distr, ymax) {

    d <- as.data.frame(
        replicate(n, 
                  expr = distr, 
                  simplify = F)
    )
    colnames(d) <- 1:n
    plot( NULL, xlim = c( min(d)-0.5, max(d)+0.5), ylim = c(0,ymax)) 
    for(i in 1:n) lines( density( d[,i]) )
}

plotcurves(n = 100, distr = rbinom(100, 1, 0.5), ymax = 2)

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

1 Ответ

0 голосов
/ 08 мая 2020

Проблема в том, что в вашей функции distr вычисляется до до того, как достигнет вызова replicate. Вы можете убедиться в этом, если сделаете вариант функции, которая просто возвращает фрейм данных d вместо его построения:

show_d <- function(n, distr, ymax) 
{
    d <- as.data.frame(
        replicate(n, 
                  expr = distr, 
                  simplify = F)
    )
  return(d)
}

show_d(n = 3, distr = rbinom(5, 1, 0.5), ymax = 2)
#>   c.1L..0L..1L..1L..1L. c.1L..0L..1L..1L..1L..1 c.1L..0L..1L..1L..1L..2
#> 1                     1                       1                       1
#> 2                     0                       0                       0
#> 3                     1                       1                       1
#> 4                     1                       1                       1
#> 5                     1                       1                       1

Вы заметите, что все столбцы одинаковы. Фактически, вызов rbinom был оценен как , затем был передан replicate, что аналогично вызову replicate(3, c(1, 0, 1, 1, 1)). Итак, вы вычерчиваете все линии - просто линии все одинаковые.

Что вам нужно сделать внутри функции, так это убедиться, что distr передается как вызывает в replicate, а не оценивает и отправляет как вектор. Вы можете сделать это, используя match.call() и извлекая третий элемент (который является вторым параметром):

plotcurves <- function(n, distr, ymax) {
    mc <- match.call()[[3]]
    d <- as.data.frame(
        replicate(n, 
                  expr = mc,
                  simplify = F)
    )
    colnames(d) <- 1:n
    plot( NULL, xlim = c( min(d)-0.5, max(d)+0.5), ylim = c(0,ymax)) 
    for(i in 1:n) lines( density( d[,i]) )
}

plotcurves(n = 100, distr = rbinom(100, 1, 0.5), ymax = 2)

enter image description here

...