我尝试使用以下参数模拟覆盖多个类的人口的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的样本大小。
感谢您的帮助。
到目前为止的最佳答案:使用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 = ":"))
}
答案 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)