计算R中年龄段和队列样本量的简便方法

计算R中年龄段和队列样本量的简便方法,r,R,在前瞻性研究中,您希望总结您的样本的年龄、观察时间以及观察时间。这些综合考虑样本的年龄、周期和队列时间尺度。 最简单的说明方法是使用模拟数据: 假设这些数据总结了一组具有基线年龄和观察开始和结束日期的临床患者: set.seed(123) n <- 10000 Obs <- data.frame( 'age' = sample(seq(40, 80, by=5), n, replace=T), 'start' = as.Date(n0 <- runif(n, 10000

在前瞻性研究中,您希望总结您的样本的年龄、观察时间以及观察时间。这些综合考虑样本的年龄、周期和队列时间尺度。

最简单的说明方法是使用模拟数据:

假设这些数据总结了一组具有基线年龄和观察开始和结束日期的临床患者:

set.seed(123)
n <- 10000
Obs <- data.frame(
  'age' = sample(seq(40, 80, by=5), n, replace=T),
  'start' = as.Date(n0 <- runif(n, 10000, 12000), origin="1970-01-01"),
  'end' = as.Date(n0 + runif(n, 0, 3652.5), origin="1970-01-01")
)
并交叉列出至少一天内落入这些值的每个可能排列中的个体数量。或者,更复杂的是,一个人属于某一类别的年数。例如,当一个人在1990年进入样本时为40岁,并在样本中停留30年,当他进入yt65/bf2000/GT5年时,他将在yt65/bf2000/GT5年类别中停留5年,当他进入yt65/af2000/GT5年类别中再停留15年,最后是ot65/af2000/GT5年

出于某种原因,这让我的大脑非常痛苦,我无法计算出实际的期望输出,即使是通过一些低效的For循环,但格式和结构如下:

        AgeCut             YrCut            DurCut  NumObs
1 younger than 65    before 2000 less than 5 years    1000
2    65 and older    before 2000 less than 5 years    1000   
3 younger than 65 2000 and later less than 5 years    1000
4    65 and older 2000 and later less than 5 years    1000
5 younger than 65    before 2000   5 or more years    1000
6    65 and older    before 2000   5 or more years    1000
7 younger than 65 2000 and later   5 or more years    1000
8    65 and older 2000 and later   5 or more years    1000

使用一些tidyverse函数,我想你需要这样的东西

library(tidyverse)
AgeCut <- c(0, 65, Inf)
Yrcut <- c(0, 2000, Inf)
DurCut <- c(0, 5, Inf)

Obs %>% transmute (
  ageCat = cut(age, AgeCut, c("younger than 65 ","65 and older"), right=FALSE),
  startCat = cut(year(start), Yrcut, c("before 2000", "2000 and later"), right=FALSE),
  DurCut = cut(year(end)-year(start), DurCut, c("less than 5 years", "5 or more years"), right=FALSE)
)  %>% table() %>% as_data_frame()
库(tidyverse)
AgeCut%作为数据帧()
这是回报

            ageCat       startCat            DurCut     n
             <chr>          <chr>             <chr> <int>
1 younger than 65     before 2000 less than 5 years  1196
2     65 and older    before 2000 less than 5 years   968
3 younger than 65  2000 and later less than 5 years  1312
4     65 and older 2000 and later less than 5 years  1015
5 younger than 65     before 2000   5 or more years  1503
6     65 and older    before 2000   5 or more years  1185
7 younger than 65  2000 and later   5 or more years  1580
8     65 and older 2000 and later   5 or more years  1241
ageCat startCat DurCut n
1 2000年前65岁以下5岁以下1196
2 2000年以前65岁及以上5岁以下968
3年龄在65岁以下2000年及5岁以下1312
4 65岁及以上2000年及5岁以下1015
5 2000年前65岁以下5岁或以上1503
6 2000年前65岁及以上5岁或以上1185
7年以下65岁2000年及5岁以上1580
8 65岁及以上2000年及5岁以上1241

cut()
函数在这里完成了大部分工作。

好的,我在base R中有这个实现。它递归地计算当前类别中花费的时间,直到移动到下一个类别,将该持续时间添加到各个计数器中,并从参与研究的总持续时间中减去,然后将更新的时间和持续时间输入到
apc
函数中

apc <- function(times, cuts, dur, strata=1) {
  class <- mapply(findInterval, times, cuts)
  tnext <- mapply( ## times until next category
    function(t, c, i) {c[i+1] - t}, 
    times, cuts, as.data.frame(class)
  )
  mnext <- apply(tnext, 1, min, na.rm=T) ## minimum time to next category
  mnext <- pmin(mnext, dur) ## truncate if duration exceeded before next
  dur <- dur-mnext
  times <- lapply(times, `+`, mnext)
  if (all(dur == 0))
    return(list(data.frame(class, 't'=mnext, strata)))
  return(c(list(data.frame(class, 't'=mnext, strata)), apc(times, cuts, dur, strata=strata)))
}

其中的总和(50061.55)等于
Obs$end Obs$start

抱歉,我的问题陈述不够清楚。这是一个很好的
tidyverse
演示。结果类似于使用
as.data.frame(表(Obs[,cutvars])
创建,其中
cutvars
cut
ted变量的派生集,如您所述。但是,请参阅我最近的编辑,其中描述了分母如何增加样本量。这对我来说是个棘手的问题。
apc <- function(times, cuts, dur, strata=1) {
  class <- mapply(findInterval, times, cuts)
  tnext <- mapply( ## times until next category
    function(t, c, i) {c[i+1] - t}, 
    times, cuts, as.data.frame(class)
  )
  mnext <- apply(tnext, 1, min, na.rm=T) ## minimum time to next category
  mnext <- pmin(mnext, dur) ## truncate if duration exceeded before next
  dur <- dur-mnext
  times <- lapply(times, `+`, mnext)
  if (all(dur == 0))
    return(list(data.frame(class, 't'=mnext, strata)))
  return(c(list(data.frame(class, 't'=mnext, strata)), apc(times, cuts, dur, strata=strata)))
}
> val
  age start cohort strata         t
1   1     1      1      1  3175.986
2   2     1      1      1  2582.793
3   1     2      1      1 17714.503
4   2     2      1      1 13972.134
5   1     2      2      1  5658.430
6   2     2      2      1  6957.702