楼主: zhaomn200145
1352 8

[程序分享] 受访者驱动抽样(RDS)的相关R程序 [推广有奖]

  • 1关注
  • 17粉丝

贵宾

已卖:254份资源

学科带头人

69%

还不是VIP/贵宾

-

威望
1
论坛币
580287 个
通用积分
80.4202
学术水平
128 点
热心指数
80 点
信用等级
43 点
经验
61461 点
帖子
1458
精华
1
在线时间
2603 小时
注册时间
2005-9-27
最后登录
2025-12-24

楼主
zhaomn200145 发表于 2023-5-29 09:49:42 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
受访者驱动抽样(RDS)是一种专门针对隐匿人群的抽样方法,常用于跨性别者、暗娼、MSM等因耻辱感和法律制度的约束难以识别和接触的人群,并逐渐应用于一般人群。这里给出国外学者写的一个相关R程序:
基本参数设定:
n <- 20000 #pop size
ns <- 500 # rds sample size
seeds <- 7 # #of seeds
#d <- round(rlnorm(n,meanlog = 1)) + 1
d <- round(rexp(n,1/5)) + 1 #heavy tailed degrees
#d <- rpois(n,lambda = 5) + 1 #light tail
#d <- rep(10, n)
g <- rep(1,n)

首先构造邻接矩阵的函数:
makeGraph <- function(d){
n <- length(d)
edges <- list()
d1 <- d
while(sum(d1)>0.5){
  l <- sample.int(n,1,prob=d1)
  dt <- d1
  dt[l] <- d1[l] - 1
  if(sum(dt) > 0.5){
   k <- sample.int(n,1,prob=dt)
   v <- TRUE
   d1[k] <- d1[k] - 1
  }else{
   k <- sample.int(n,1,prob=d)
   v <- FALSE
  }
  d1[l] <- d1[l] - 1
  edges[[length(edges)+1]] <- c(l,k,v)
}
el <- do.call(rbind,edges)
el
}
el <- makeGraph(d)   #el即为相关联的矩阵

构造RDS抽样函数:
sampRDS <- function(el, d, ns, g, ss, biased=TRUE,pr = c(0,.1,.9)){
maxR <- length(pr) -1
n <- length(g)
ml <- if(is.factor(g)) max(levels(g)) else max(g)
if(biased){
  seeds <- sample.int(n,ns,prob=as.numeric(as.factor(g))-1)
}else{
  seeds <- sample.int(n,ns, prob = d)
}
samp <- seeds
recr <- rep(-1,ns)
time <- 0 + (1:ns)/10000000
rcTime <- rexp(ns)
v <- rep(-1,ns)
t1 <- time
while(length(samp) < ss){
  subjIndex <- which.min(t1 + rcTime)
  if(length(subjIndex)==0){
   print("redraw")
   subj <- sample( (1:n)[-samp],1)
   samp <- c(samp,subj)
   recr <- c(recr,-1)
   time <- c(time,max(time+1))
   rcTime <- c(rcTime,rexp(1))
   t1 <- c(t1,max(time+1))
   v <- c(v,-1)
  }else{
   t <- t1[subjIndex] + rcTime[subjIndex]
   t1[subjIndex] <- NA
   subj <- samp[subjIndex]
   nr <- sample(0:maxR,1,replace=FALSE,prob=pr)
   nbrs <- rbind(el[el[,1]==subj,2:3,drop=FALSE],
                 el[el[,2]==subj & el[,3]>0.5,c(1,3),drop=FALSE]
   )
   nbrs <- nbrs[!(nbrs[,1] %in% samp) & nbrs[,1]!=subj,,drop=FALSE]
   nr <- min(nr,nrow(nbrs))
   if(nr>0){
    s <- sample.int(nrow(nbrs),nr,replace=FALSE)
    s <- s[!duplicated(nbrs[s,1])]
    nr <- length(s)
    samp <- c(samp,nbrs[s,1])
    recr <- c(recr,rep(subj,nr))
    tm <- t + t + (0:(nr-1)) / 1000000
    time <- c(time,tm)
    t1 <- c(t1,tm)
    rcTime <- c(rcTime,rexp(nr))
    v <- c(v,nbrs[s,2])
   }
  }
}
data.frame(subject=samp,recruiter=recr,time=time,v=v)
}


rds <- sampRDS(el, d, seeds,g,ns,FALSE, pr = c(0,.1,.9))

基本函数如上。



二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:RDS 受访者 R程序 法律制度 参数设定

沙发
zhaomn200145 发表于 2023-5-29 09:51:19
虽然可以跑出结果,但是说实话这两个函数中的一些命令还是没太看明白。

藤椅
zhaomn200145 发表于 2023-5-29 10:00:57
欢迎有兴趣的朋友一起参与讨论。

板凳
Raymond.K 学生认证  发表于 2023-5-29 10:01:59
感谢分享,有原链接或者参考文献吗

报纸
zhaomn200145 发表于 2023-5-29 10:04:27
关于RDS检验可以看一下康奈尔Heckathorn教授的文章。

地板
zhaomn200145 发表于 2023-6-7 10:01:57
从邻接矩阵el中进行抽取的关键函数部分:while(length(samp) < ss){
  subjIndex <- which.min(t1 + rcTime)
  if(length(subjIndex)==0){
   print("redraw")
   subj <- sample( (1:n)[-samp],1)
   samp <- c(samp,subj)
   recr <- c(recr,-1)
   time <- c(time,max(time+1))
   rcTime <- c(rcTime,rexp(1))
   t1 <- c(t1,max(time+1))
   v <- c(v,-1)
  }else{
   t <- t1[subjIndex] + rcTime[subjIndex]
   t1[subjIndex] <- NA
   subj <- samp[subjIndex]
   nr <- sample(0:maxR,1,replace=FALSE,prob=pr)
   nbrs <- rbind(el[el[,1]==subj,2:3,drop=FALSE],
                 el[el[,2]==subj & el[,3]>0.5,c(1,3),drop=FALSE]
   )
   nbrs <- nbrs[!(nbrs[,1] %in% samp) & nbrs[,1]!=subj,,drop=FALSE]
   nr <- min(nr,nrow(nbrs))
   if(nr>0){
    s <- sample.int(nrow(nbrs),nr,replace=FALSE)
    s <- s[!duplicated(nbrs[s,1])]
    nr <- length(s)
    samp <- c(samp,nbrs[s,1])
    recr <- c(recr,rep(subj,nr))
    tm <- t + t + (0:(nr-1)) / 1000000
    time <- c(time,tm)
    t1 <- c(t1,tm)
    rcTime <- c(rcTime,rexp(nr))
    v <- c(v,nbrs[s,2])
   }
  }
这个地方始终没研究明白,不知有没有高人可以解释一下这其中的步骤。

7
zhaomn200145 发表于 2023-6-13 10:17:55
如果从RDS函数中把上面的程序单独抽取出来运行的话,结果就会报错。

8
zhaomn200145 发表于 2023-6-13 10:37:53
还有一点不懂的:在function(RDS)中写的这个循环:while(length(samp) < ss) {}中为什么没有终止命令?不知哪位高人可以指点一二,谢谢。

9
zhaomn200145 发表于 2023-6-13 10:50:02
在function(RDS)中还有这一部分:
if(nr>0){
    s <- sample.int(nrow(nbrs),nr,replace=FALSE)
    s <- s[!duplicated(nbrs[s,1])]
    nr <- length(s)
    samp <- c(samp,nbrs[s,1])
    recr <- c(recr,rep(subj,nr))
    tm <- t + t + (0:(nr-1)) / 1000000
    time <- c(time,tm)
    t1 <- c(t1,tm)
    rcTime <- c(rcTime,rexp(nr))
    v <- c(v,nbrs[s,2])
   }
然后没有对应的else{}

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-29 09:20