为R中的模拟样本按类生成ID号

时间:2015-03-15 22:40:14

标签: r simulation random-sample

我尝试使用以下参数模拟覆盖多个类的人口的ID号

  • 每个班级按照相同的模式顺序分配ID。
  • 每个班级' ID前缀与其他所有类不同。前缀。

生成一些示例数据

data(mtcars)
set.seed(9999)
mtcars$count<-sample(x = 1:100,size = 32,replace=T)
mtcars
Car.Sample<-sample(1:sum(mtcars$count),15)

所以,我模拟了人口中的15辆汽车(1774年)。我最初想到如何计算样本中每个成员的ID号是使用我采样的数字并滚动mtcars的记录,直到计数总和超过样本数。然后从该记录之前的所有记录中减去计数总和,余数是该类中汽车的ID号。 e.g。

Car.ID<-function(x){
  Commute <- 0
  Counter <- 0
  while (Commute<x){
    Counter <- Counter + 1
    Commute <- Commute + mtcars[Counter,'count']
  }

  # we overshot the count so we need to step back one iteration
  Commute <- Commute - mtcars[Counter,'count']

  Class <- rownames(mtcars)[Counter]
  ID.Num <- x - Commute
  temp <- paste(Class,ID.Num,sep=':')
  return(temp)
}

此函数生成正确的结果,如果我输入每个可能的样本编号,我会得到一个与上述规则一致的已分配ID列表。问题是它比吐痰慢。我的实际用例有1000个类,我可能需要模拟大小为10 ^ 5或10 ^ 6的样本大小。

  1. 有没有办法优化这种逻辑?
  2. 是否有更有效的逻辑来分配这些ID?
  3. 感谢您的帮助。

    到目前为止的最佳答案:使用cumsum函数(@patabongo)优化

    mtcars$Commute <- cumsum(mtcars$count)
    Car.ID <- function(x) {
      row <- head(which(mtcars$Commute >= x), n = 1)
      Commutation <- mtcars$Commute[row-1]
      if (length(Commutation)==0) {Commutation <- 0}
      return(paste(rownames(mtcars)[row], x - Commutation, sep = ":"))
    }
    

1 个答案:

答案 0 :(得分:1)

一种方法是将累积和列分配给mtcars,这样您就不必一直重新计算。

mtcars$cumsum <- cumsum(mtcars$count)

Car.ID <- function(x) {
    if (x < mtcars$cumsum[1]) {
        return(paste(rownames(mtcars)[1], x, sep = ":"))
    } else {
        row <- tail(which(mtcars$cumsum < x), n = 1)
        return(paste(rownames(mtcars)[row + 1], x - mtcars$cumsum[row], sep = ":"))
    }
}

sapply(Car.Sample, Car.ID)