添加缺少数据的NA

时间:2017-04-27 17:25:10

标签: r

我有一个类似于以下

的数据集
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。所以我希望我的数据集看起来如下:

> 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语句来解决这个问题,但是代码非常冗长且繁琐(我的真实数据集中有更多的列)。

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

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:1)

基于包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)

答案 2 :(得分:1)

以下是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)]