使用dplyr的complete函数扩展数据集以补充0值
按地点自身年份范围补全数据集缺失值
问题背景
现有一份动物采样数据集,包含不同地点、年份的动物年龄组、雌性比例(propF)和雄性数量(nM)。需要为每个地点自身调查年份范围内,补充未记录对应年龄组的0值,且不能改变各地点原有的年份范围(例如地点B仅保留2002-2009年数据,地点A保留2000-2010年)。此前使用df %>% complete(year, nesting(site, age), fill = list(propF = 0))会统一所有地点的年份范围,不符合需求。
示例数据
df <- structure(list( site = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), levels = c("A", "B"), class = "factor"), year = c(2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2002, 2005, 2006, 2007, 2008, 2009, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2000, 2001, 2003, 2005), age = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), levels = c("1", "2"), class = "factor"), propF = c(0, 0, 0, 0, 0, 0.1, 0, 0, 0.2, 0.5, 1, 0.8, 0.8, 0.8, 0, 0.2, 0.2, 0.1, 0.3, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 1, 0.9, 1, 1), nM = c(48L, 30L, 41L, 30L, 22L, 23L, 81L, 29L, 4L, 1L, 0L, 3L, 1L, 3L, 23L, 14L, 43L, 42L, 29L, 30L, 72L, 88L, 83L, 17L, 65L, 0L, 1L, 0L, 0L)), row.names = c(NA, -29L), class = c("tbl_df", "tbl", "data.frame")) print(df, n=30)
解决方案
核心思路是按地点分组后再补全缺失值,这样每个地点只会基于自身的年份范围生成缺失的年龄组记录,不会被其他地点的年份范围干扰。具体代码如下:
library(dplyr) library(tidyr) df_completed <- df %>% group_by(site) %>% # 按地点分组,确保每组仅处理自身年份范围 complete(year, age, fill = list(propF = 0, nM = 0)) %>% # 补全年份+年龄组的缺失项,指定填充值 ungroup() # 取消分组,恢复数据集结构
结果验证
- 地点A的年份范围仍为2000-2010年,年龄组2会自动补充2002、2004、2006-2010年的
propF和nM为0 - 地点B的年份范围保持2002-2009年,原有数据无变化(示例中地点B已覆盖所有年龄组,因此无新增行)
内容的提问来源于stack exchange,提问作者tnt
相关产品推荐
相关产品推荐

