R - 预定义总数的整数随机近似正态分布

5

我正在尝试创建一个数据集,其中包含具有特定属性的随机生成值:

  • 所有大于0的正整数
  • 在两列(x,y)中,它们的和相等(sum(x) == sum(y))
  • 具有近似正态分布

我已经成功地创建了一些接近所需数据的生成器,但速度非常慢。 我认为这是由于while循环导致的。

simSession <- function(sessionid = 1) {
    s <- data.frame(sessionid = sessionid, userid = seq(1:12))
    total <- sample(48:72, 1)

    mu = total / 4
    sigma = 3

    s$x <- as.integer(rnorm(mean=mu, sd=sigma, n=nrow(s)))
    while(sum(s$x) > total) {
        # i <- sample(nrow(s), 1)
        i <- sample(rep(s$userid, s$x), 1)
        if(s[i, ]$x > 1) {
            s[i, ]$x <- s[i, ]$x - 1
        } else {
            s[i, ]$x = 1
        }
    }

    s$y <- as.integer(rnorm(mean=mu, sd=sigma, n=nrow(s)))
    while(sum(s$y) > sum(s$x)) {
        # i <- sample(nrow(s), 1)
        i <- sample(rep(s$userid, s$y), 1)
        if(s[i, ]$y > 1) {
            s[i, ]$y <- s[i, ]$y - 1
        } else {
            s[i, ]$y = 1
        }
    }

    s$xyr <- s$x / s$y

    return(s)
}

有没有什么明显的问题我忽略了,可以使这个问题更容易解决或者有更快的替代函数?

此外,如果能指定一个参数来偏移模式到左或右将会得到额外的分数。

1个回答

0
如果您不介意期望值和方差相等,您可以使用泊松分布:
randgen <- function(n,mu) {
  x <- rpois(n,mu)
  y <- rpois(n,mu)

  d <- sum(y)-sum(x)

  if (d<0) {
    ind <- sample(seq_along(y),-d)
    y[ind] <- y[ind]+1
  } else {
    ind <- sample(seq_along(x),d)
    x[ind] <- x[ind]+1
  }

 cbind(x=as.integer(x),y=as.integer(y))
}

set.seed(42)
rand <- randgen(1000,15)

layout(c(1,2))    
qqnorm(rand[,1]); qqline(rand[,1])
qqnorm(rand[,2]); qqline(rand[,2])

enter image description here

is.integer(rand)
#[1] TRUE

sum(rand<0)
#[1] 0

colSums(rand)
#x     y 
#15084 15084

mean(rand[,1])
#[1] 15.084
mean(rand[,2])
#[1] 15.084

sd(rand[,1])
#[1] 4.086275
sd(rand[,2])
#[1] 3.741249

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接