9

假设我有一组我怀疑来自同一分布的数字。

set.seed(20130613)
x <- rcauchy(10)

我想要一个从相同的未知分布中随机生成数字的函数。我想到的一种方法是创建一个density对象,然后从中获取 CDF 并获取随机统一变量的逆 CDF (参见 Wikipedia)

den <- density(x)

#' Generate n random numbers from density() object
#' 
#' @param n The total random numbers to generate
#' @param den The density object from which to generate random numbers
rden <- function(n, den)
{
        diffs <- diff(den$x)
        # Making sure we have equal increments
        stopifnot(all(abs(diff(den$x) - mean(diff(den$x))) < 1e-9))
        total <- sum(den$y)
        den$y <- den$y / total
        ydistr <- cumsum(den$y)
        yunif <- runif(n)
        indices <- sapply(yunif, function(y) min(which(ydistr > y)))
        x <- den$x[indices]

        return(x)
}

rden(1, den)
## [1] -0.1854121

我的问题如下:

  1. 是否有更好的(或内置于 R 中)从密度对象生成随机数的方法?
  2. sample关于如何从一组数字(除了)生成随机数还有其他想法吗?
4

3 回答 3

12

要从密度估计中生成数据,您只需随机选择一个原始数据点并根据密度估计中的内核添加一个随机“错误”片段,对于“高斯”的默认值,这仅意味着从原始向量并添加一个均值为 0 且 sd 等于所用带宽的随机法线:

den <- density(x)

N <- 1000
newx <- sample(x, N, replace=TRUE) + rnorm(N, 0, den$bw)

logspline另一种选择是使用包中的函数拟合密度logspline(使用不同的估计密度的方法),然后使用该rlogspline包中的函数从估计的密度生成新数据。

于 2013-06-13T16:22:14.713 回答
2

如果您只需要从现有的数字池中提取值,那么sample就是要走的路。
如果您想从假定的基础分布中提取,请使用density,并将其拟合到假定的分布以获得必要的系数(均值、标准差等),并使用适当的R分布函数。

除此之外,我会看一下 C 中的数值食谱的第 7.3 章(“拒绝方法”),以了解根据任何分布“选择性”采样的方法。代码很简单,可以很容易地翻译成R . 我敢打赌,有人已经这样做了,并且会发布比这更好的答案。

于 2013-06-13T13:30:40.857 回答
0

Greg Snow 的回答对我很有帮助,我意识到密度函数的输出具有从输入分布创建随机数所需的所有数据。基于他的示例,您可以执行以下操作以使用密度输出获取随机值。

x <- rnorm(100)   # or any numeric starting vector you desire
dens <- density(x)
N <- 1000
newx <- sample(x = dens$x, N, prob = dens$y, replace=TRUE) + rnorm(N, 0, dens$bw)

您甚至可以创建一个简单的随机数生成函数

rdensity <- function(n, dens) {
    return(sample(x = dens$x, n, prob = dens$y, replace=TRUE) + rnorm(n, 0, dens$bw))
}
于 2021-03-16T11:14:56.487 回答