我想在R
中重新创建这个Stata命令 by Area Sex Age: keep if (Infected==1) | ((_n<=1*ncases) & (Infected==0))
这是一个匹配的病例对照研究
我的数据框包含193个案例和每组可变数量的控件(区域性别和年龄)。我试图根据区域性别和年龄的分组将1个随机控制与每个案例相匹配。
ncases 是我的数据框中的一个整数,表示每个组中的个案数量(区域性别年龄)
上面的命令行在Stata中运行良好。
但是,我编写的R代码仅适用于第一组:
dat5 <- subset(dat4,by=list(Area,Sex,Age),(Infected=1 |
((seq(dim(dat4)[1]))<=1*ncases & Infected==0)))
这是我的数据帧dat4:感染= 1是一个案例,被感染= 0是一个控件。
Area Sex Age CensusNo Animals Infected ncases
18825 1 1 23 1023224 0 0 1
18826 1 1 23 1024109 1 0 1
18827 1 1 23 1024163 0 1 1
41428 7 2 50 1047107 1 0 1
41429 7 2 50 1047029 1 0 1
41430 7 2 50 1046901 1 1 1
41439 5 1 36 1047037 1 0 2
41440 5 1 36 1047127 1 0 2
41441 5 1 36 1047125 1 0 2
41442 5 1 36 1047005 1 0 2
41443 5 1 36 1046994 0 1 2
41444 5 1 36 1046972 0 1 2
答案 0 :(得分:1)
by
功能中没有subset
参数。我将构建一个索引向量,对于案例和每个类别中的控件样本都是TRUE:
chosen <- by(dat4, INDICES= list(Area,Sex,Age),
FUN=function(d) {
idx <- d[['Infected']]==1 |
(d[['Infected']]==0 & sample( (1:NROW(d)) <= d[["ncases"]][1] ))
return( d[idx,]}
chosen <- do.call(rbind, chosen)
最后一部分让我觉得有点笨拙。我正在构建一个逻辑值向量,然后用sample
函数置换它。 by
函数返回一个列表,其中包含每个类别的条目。在这种情况下,您需要rbind
来“叠加”。我怀疑有一种更有表现力的方法来进行取样,那些神经通路只需要更多的咖啡因。 (在您为此目的提供样本数据集之前,也未经测试。)
答案 1 :(得分:1)
data.table
解决方案。
library(data.table)
ddd <- data.table(dat4)
ddd[, {
# coerce integer Infected to logical
# not really necessary, but for robustness
ii <- as.logical(Infected)
# if Infected == 1, then ii == TRUE
if(ii){ # if TRUE, keep all cases
.SD
} else {
# alternatively keep a sample of
# the
.SD[sample.int(.N, size = ncases)]
}
} , by=list(Area,Sex,Age,ncases, Infected)]