向数据框添加行以进行非观察

时间:2018-12-17 14:55:42

标签: r dplyr

我有一个数据框,该数据框总结了白天(即当太阳在地平线上方)每天和每小时在繁殖场观察到鸟类的次数。例如:

head(df)
    ID   site day  hr  nObs
1    19  A    202  11  60
2    19  A    202  13  18
3    19  A    202  15  27
4     8  B    188  8   6
5     8  B    188  9   6
6     8  B    188  11  7

但是,此数据框不包括未观察到鸟类的小时数。例如。第202天第14天的19鸟没有任何直线,nObs值为0。

我想找到一种方法,最好是使用dplyr(整洁的经文),在未观察到个体时添加这些行。

2 个答案:

答案 0 :(得分:3)

您可以使用complete中的tidyr,即

library(tidyverse)

df %>% 
 group_by(ID, site) %>% 
 complete(hr = seq(min(hr), max(hr)))

给出,

# A tibble: 9 x 5
# Groups:   ID, site [2]
     ID site     hr   day  nObs
  <int> <fct> <int> <int> <int>
1     8 B         8   188     6
2     8 B         9   188     6
3     8 B        10    NA    NA
4     8 B        11   188     7
5    19 A        11   202    60
6    19 A        12    NA    NA
7    19 A        13   202    18
8    19 A        14    NA    NA
9    19 A        15   202    27

答案 1 :(得分:1)

一种方法是首先建立一个可以观察鸟类的所有可能组合的“模板”,然后将实际观察结果合并(“左连接”)到该模板上:

a = read.table(text = "    ID   site day  hr  nObs
1    19  A    202  11  60
2    19  A    202  13  18
3    19  A    202  15  27
4     8  B    188  8   6
5     8  B    188  9   6
6     8  B    188  11  7")


tpl <- expand.grid(c(unique(a[, 1:3]), list(hr = 1:24)))
merge(tpl, a, all.x = TRUE)

根据@ user3220999的注释进行编辑:如果我们要按ID进行处理,我们可以使用split来获取数据列表。每个ID的帧数,获取模板和mapply合并到两个列表中:

a <- split(a, a$ID)
tpl <- lapply(a, function(ai) {
  expand.grid(c(unique(ai[, 1:3]), list(hr = 1:24))) 
})
res <- mapply(merge, tpl, a, SIMPLIFY = FALSE, MoreArgs = list(all.x = TRUE))