我正在使用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)
解决方案似乎非常简单,但我似乎找不到。我需要做些什么来修复代码,或者我已经不知道这样的功能已经存在?
问题在于,在您的函数中,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)