我有一个数据框,该数据框总结了白天(即当太阳在地平线上方)每天和每小时在繁殖场观察到鸟类的次数。例如:
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(整洁的经文),在未观察到个体时添加这些行。
答案 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))