【问题标题】:Adding NA's where data is missing [duplicate]在数据丢失的地方添加 NA [重复]
【发布时间】:2017-04-27 17:25:10
【问题描述】:

我有一个如下所示的数据集

id = c(1,1,1,2,2,2,3,3,4)
cycle = c(1,2,3,1,2,3,1,3,2)
value = 1:9

data.frame(id,cycle,value)

> data.frame(id,cycle,value)
  id cycle value
1  1     1     1
2  1     2     2
3  1     3     3
4  2     1     4
5  2     2     5
6  2     3     6
7  3     1     7
8  3     3     8
9  4     2     9

所以基本上有一个名为id 的变量用于标识样本,一个名为cycle 的变量用于标识时间点,还有一个名为value 的变量用于标识该时间点的值。

如您所见,样本 3 没有周期 2 数据,样本 4 缺少周期 1 和 3 数据。我想知道的是有一种方法可以在循环之外运行命令以获取数据以将NA's 放置在没有数据的地方。所以我希望我的数据集如下所示:

> data.frame(id,cycle,value)
   id cycle value
1   1     1     1
2   1     2     2
3   1     3     3
4   2     1     4
5   2     2     5
6   2     3     6
7   3     1     7
8   3     2    NA
9   3     3     8
10  4     1    NA
11  4     2     9
12  4     3    NA

我可以通过大量循环和 if 语句来解决这个问题,但代码非常长且繁琐(我的真实数据集中有更多列)。

另外,我拥有的样本数量非常多,所以我需要一些可推广的东西。

【问题讨论】:

    标签: r


    【解决方案1】:

    使用mergeexpand.grid,我们可以想出一个解决方案。 expand.grid 使用所提供向量的所有组合创建一个 data.frame(因此您可以为其提供 idcycle 变量)。通过合并到您的原始数据(并使用all.x = T,类似于SQL 中的left join),我们可以用NA 填充dat 中缺少数据的那些行。

    id = c(1,1,1,2,2,2,3,3,4)
    cycle = c(1,2,3,1,2,3,1,3,2)
    value = 1:9
    
    dat <- data.frame(id,cycle,value)
    
    grid_dat <- expand.grid(id = 1:4,
                            cycle = 1:3)
    
    # or you could do (HT @jogo):
    # grid_dat <- expand.grid(id = unique(dat$id), 
    #                         cycle = unique(dat$cycle))
    
    merge(x = grid_dat, y = dat, by = c('id','cycle'), all.x = T)
    
       id cycle value
    1   1     1     1
    2   1     2     2
    3   1     3     3
    4   2     1     4
    5   2     2     5
    6   2     3     6
    7   3     1     7
    8   3     2    NA
    9   3     3     8
    10  4     1    NA
    11  4     2     9
    12  4     3    NA
    

    【讨论】:

    • grid_dat &lt;- expand.grid(id = unique(dat$id), cycle = unique(dat$cycle))
    【解决方案2】:

    基于包tidyverse的解决方案。

    library(tidyverse)
    
    # Create example data frame
    id <- c(1, 1, 1, 2, 2, 2, 3, 3, 4)
    cycle <- c(1, 2, 3, 1, 2, 3, 1, 3, 2)
    value <- 1:9
    
    dt <- data.frame(id, cycle, value)
    
    # Complete the combination between id and cycle
    dt2 <- dt %>% complete(id, cycle)
    

    【讨论】:

    • 我的话,@hadley 已经想到了一切
    【解决方案3】:

    这是data.table 进行交叉连接的解决方案:

    library("data.table")
    d <- data.table(id = c(1,1,1,2,2,2,3,3,4), cycle = c(1,2,3,1,2,3,1,3,2), value = 1:9)
    d[CJ(id=id, cycle=cycle, unique=TRUE), on=.(id,cycle)]
    

    【讨论】:

      猜你喜欢
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 2013-02-16
      • 1970-01-01
      • 2012-10-04
      • 1970-01-01
      • 2020-06-10
      相关资源
      最近更新 更多