【问题标题】:How to create missing value for repeated measurement data?如何为重复测量数据创建缺失值?
【发布时间】:2015-09-18 14:38:43
【问题描述】:

我有一个数据集,并非每个受试者的观察结果都是在完全相同的时间点观察到的,但我想将其转换为每个人的观察结果都在完全相同的时间点观察到的数据集(这样我就可以在 SAS proc traj 中使用它)。

例如,假设我有数据集“m”:

id   <- c(1,1,1,1,2,2,3,3,3)
age  <- c(2,3,4,5,3,6,2,5,8)
IQ   <- c(3,4,5,4,6,5,3,8,10)
m    <- data.frame(id,age,IQ)
> m
  id age IQ
1  1   2  3
2  1   3  4
3  1   4  5
4  1   5  4
5  2   3  6
6  2   6  5
7  3   2  3
8  3   5  8
9  3   8 10
> unique(age)
[1] 2 3 4 5 6 8

我想把 m 变成 m2。但我只能手动完成。

id2   <- c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)
age2  <- c(2,3,4,5,6,8,2,3,4,5,6,8,2,3,4,5,6,8) 
IQ2   <- c(3,4,5,4,NA,NA,6,5,NA,NA,NA,NA,3,8,10,NA,NA,NA) 
m2    <- data.frame(id2,age2,IQ2)    
m2
> m2
   id2 age2 IQ2
1    1    2   3
2    1    3   4
3    1    4   5
4    1    5   4
5    1    6  NA
6    1    8  NA
7    2    2   6
8    2    3   5
9    2    4  NA
10   2    5  NA
11   2    6  NA
12   2    8  NA
13   3    2   3
14   3    3   8
15   3    4  10
16   3    5  NA
17   3    6  NA
18   3    8  NA

有人知道更聪明的方法吗?

【问题讨论】:

    标签: r repeat missing-data


    【解决方案1】:

    使用 tidyr,这是一个单一的衬里。您使用 complete 函数,它使用传递给它的列的每个组合创建行,用 NA 填充其余行:

    library(tidyr)
    complete(m, id, age)
    
    Source: local data frame [18 x 3]
    
          id   age    IQ
       (dbl) (dbl) (dbl)
    1      1     2     3
    2      1     3     4
    3      1     4     5
    4      1     5     4
    5      1     6    NA
    6      1     8    NA
    7      2     2    NA
    8      2     3     6
    9      2     4    NA
    10     2     5    NA
    11     2     6     5
    12     2     8    NA
    13     3     2     3
    14     3     3    NA
    15     3     4    NA
    16     3     5     8
    17     3     6    NA
    18     3     8    10
    

    【讨论】:

    【解决方案2】:

    我们可以使用data.table 做到这一点。我们将 data.frame 转换为 data.table (setDT(m)),设置键列 (setkey) 并使用 'id' 和 'age' 的unique 元素的交叉连接加入

    library(data.table)
    setkey(setDT(m), id, age)[CJ(unique(id), unique(age))]
    #    id age IQ
    # 1:  1   2  3
    # 2:  1   3  4
    # 3:  1   4  5
    # 4:  1   5  4
    # 5:  1   6 NA
    # 6:  1   8 NA
    # 7:  2   2 NA
    # 8:  2   3  6
    # 9:  2   4 NA
    #10:  2   5 NA
    #11:  2   6  5
    #12:  2   8 NA
    #13:  3   2  3
    #14:  3   3 NA
    #15:  3   4 NA
    #16:  3   5  8
    #17:  3   6 NA
    #18:  3   8 10
    

    在开发版本中,即v1.9.5,我们可以在CJ 中使用unique=TRUE(来自@Frank 的评论)

    setDT(m, key=c('id', 'age'))[CJ(id, age, unique=TRUE)]
    

    基准测试

    set.seed(24)
    m1 <- data.frame(id=rep(1:10000, each=10), age=sample(2:400, 10000*10, 
             replace=TRUE), IQ=rnorm(10000*10))
    system.time(res1 <- complete(m1, id, age))
    # user  system elapsed 
    #18.888   0.000  16.258 
    
    
    system.time({ DT <- as.data.table(m1)
             res2 <- setkey(DT, id, age)[CJ(unique(id), unique(age))]})
    #  user  system elapsed 
    #  0.000   0.000   0.279 
    
    
    
    library(microbenchmark)
    jeremy <- function() complete(m1, id, age)
    akrun <- function() {DT <- as.data.table(m1)
       setkey(DT, id, age)[CJ(unique(id), unique(age))]}
    
    microbenchmark(jeremy(), akrun(), times=20L, unit='relative')
    #Unit: relative
    #   expr      min       lq   mean   median       uq      max neval cld
    #jeremy() 24.95042 30.84234 17.138 23.09175 12.16891 8.305394    20   b
    # akrun()  1.00000  1.00000  1.000  1.00000  1.00000 1.000000    20  a 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-17
      • 2022-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-15
      相关资源
      最近更新 更多