按区域性别和年龄在R中重新创建Stata命令:keep if(Infected == 1)| ((_n< = 1 * ncases)&(Infected == 0))

时间:2013-04-03 13:44:00

标签: r stata

我想在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 

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)]