我正在创建一些人工数据。我需要创建家庭ID(H_ID)和个人ID(每个家庭中的P_ID)。

我找到了一种如何以 vector 化方式创建H_ID的方法。

N <- 50

### Household ID
# loop-for
set.seed(20110224)
H_ID <- vector("integer", N)
H_ID[1] <- 1
for (i in 2:N) if (runif(1) < .5) H_ID[i] <- H_ID[i-1]+1 else H_ID[i] <- H_ID[i-1]
print(H_ID)

# vectorised form
set.seed(20110224)
r <- c(0, runif(N-1))
H_ID <- cumsum(r < .5)
print(H_ID)

但是我不知道如何以 vector 化方式创建P_ID。
### Person ID
# loop-for
P_ID <- vector("integer", N)
P_ID[1] <- 1
for (i in 2:N) if (H_ID[i] > H_ID[i-1]) P_ID[i] <- 1 else P_ID[i] <- P_ID[i-1]+1
print(cbind(H_ID, P_ID))

# vectorised form
# ???

最佳答案

Martin Morgan's solution启发,它涉及到一个密切相关的问题,这是一种真正的 vector 化方法,可以使用P_ID函数生成cummax。一旦您注意到P_IDcumsum!(r < 0.5)紧密相关,就会很清楚:

set.seed(1)
N <- 10
r <- c(0, runif(N-1))
H_ID <- cumsum(r < .5)
r_ <- r >= .5 # flip the coins that generated H_ID.
z <- cumsum(r_)  # this is almost P_ID; just need to subtract the right amount...
# ... and the right amount to subtract is obtained via cummax
P_ID <- 1 + z - cummax( z * (!r_) )
> cbind(H_ID, P_ID)
      H_ID P_ID
 [1,]    1    1
 [2,]    1    2
 [3,]    2    1
 [4,]    3    1
 [5,]    3    2
 [6,]    3    3
 [7,]    3    4
 [8,]    4    1
 [9,]    5    1
[10,]    5    2

我没有做详细的时序测试,但是它可能很快,因为它们都是内部的 vector 化函数

关于r - 向量化循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5111439/

10-09 17:09
查看更多