如何在单个R函数中模拟数据和可视化

问题描述 投票:1回答:1

我正在使用replicate模拟R中的分布,并可视化它们如何随着不同的参数(例如rbinom(100,1,0.5)rbinom(100,1,0.01))而变化。

我想在一个函数中执行所有这些操作,该函数1.模拟复制,2.设置绘图尺寸和参数,并3.循环并绘制密度曲线。

在单独的代码中,此代码没有问题:

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)

解决方案似乎非常简单,但我似乎找不到。我需要做些什么来修复代码,或者我已经不知道这样的功能已经存在?

r function data-visualization simulation distribution
1个回答
0
投票

问题在于,在您的函数中,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的调用被评估为[[then传递给replicate,这与调用replicate(3, c(1, 0, 1, 1, 1))相同。因此,您are绘制了所有线条-只是线条都相同。

在函数内部需要做的是确保distr作为

call传递给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
© www.soinside.com 2019 - 2024. All rights reserved.