通过 class 为 R 中的模拟样本生成 ID 号

Generating ID numbers by class for a simulated sample in R

我正在尝试使用以下参数

模拟涵盖多个 class 的人口的 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)

因此,我模拟了人口 (1774) 中的 15 辆汽车。对于如何计算样本中每个成员的 ID 号,我最初的想法是使用我采样的数字,并向下滚动 mtcars 的记录,直到计数之和超过样本数。然后将之前的所有记录减去count之和,余数就是class里面那辆车的ID号。例如

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 列表。问题是它比 spit 慢。我的实际用例有 1000 classes,我可能需要模拟 10^5 或 10^6 数量级的样本量。

  1. 有没有办法优化这个逻辑?
  2. 是否有更有效的逻辑来分配这些 ID?

感谢您的帮助。

迄今为止的最佳答案:使用 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 = ":"))
}

一种方法是将累积和列分配给 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)