如何在R中补全数据集缺失年份行并修正年龄计算?
问题背景
现有如下R数据集:
name = c("john", "john", "john", "sarah", "sarah", "peter", "peter", "peter", "peter") year = c(2010, 2011, 2014, 2010, 2015, 2011, 2012, 2013, 2015) age = c(21, 22, 25, 55, 60, 61, 62, 63, 65) gender = c("male", "male", "male", "female", "female", "male", "male", "male", "male" ) country_of_birth = c("australia", "australia", "australia", "uk", "uk", "mexico", "mexico", "mexico", "mexico") my_data = data.frame(name, year, age, gender, country_of_birth)
数据集预览:
name year age gender country_of_birth 1 john 2010 21 male australia 2 john 2011 22 male australia 3 john 2014 25 male australia 4 sarah 2010 55 female uk 5 sarah 2015 60 female uk 6 peter 2011 61 male mexico 7 peter 2012 62 male mexico 8 peter 2013 63 male mexico 9 peter 2015 65 male mexico
需要为每个人员补全缺失年份的行,要求:
- age变量逐年递增1(例如John在2012年应为23岁,2013年应为24岁)
- gender变量保持不变
- country_of_birth变量保持不变
原使用的R代码:
library(tidyr) library(dplyr) my_data %>% group_by(name) %>% complete(year = full_seq(year, period = 1)) %>% fill(year, age, gender, country_of_birth, .direction = "downup") %>% mutate(real_age= age - (row_number() - 1)) %>% ungroup
注:原代码中的%>%为转义后的管道符,实际使用时应为%>%
但代码计算出的age结果不正确,输出结果:
# A tibble: 16 x 6 name year age gender country_of_birth real_age <chr> <dbl> <dbl> <chr> <chr> <dbl> 1 john 2010 21 male australia 21 2 john 2011 22 male australia 21 3 john 2012 22 male australia 20 4 john 2013 22 male australia 19 5 john 2014 25 male australia 21 6 peter 2011 61 male mexico 61 7 peter 2012 62 male mexico 61 8 peter 2013 63 male mexico 61 9 peter 2014 63 male mexico 60 10 peter 2015 65 male mexico 61 11 sarah 2010 55 female uk 55 12 sarah 2011 55 female uk 54 13 sarah 2012 55 female uk 53 14 sarah 2013 55 female uk 52 15 sarah 2014 55 female uk 51 16 sarah 2015 60 female uk 55
修正代码及解释
原代码中mutate(real_age= age - (row_number() - 1))的逻辑错误,填充后的age值无法作为统一基准计算年龄。正确思路是基于每个人的初始年龄与年份差推导逐年年龄:
修正后的代码:
library(tidyr) library(dplyr) my_data %>% group_by(name) %>% # 补全所有缺失年份 complete(year = full_seq(year, period = 1)) %>% # 填充固定不变的字段 fill(gender, country_of_birth, .direction = "downup") %>% # 基于初始年龄和年份差计算正确年龄 mutate( earliest_year = first(year), initial_age = age[year == earliest_year], real_age = initial_age + (year - earliest_year) ) %>% # 移除辅助计算列(可选) select(-earliest_year, -initial_age) %>% ungroup()
运行后的正确结果:
# A tibble: 16 x 5 name year age gender country_of_birth real_age <chr> <dbl> <dbl> <chr> <chr> <dbl> 1 john 2010 21 male australia 21 2 john 2011 22 male australia 22 3 john 2012 22 male australia 23 4 john 2013 22 male australia 24 5 john 2014 25 male australia 25 6 peter 2011 61 male mexico 61 7 peter 2012 62 male mexico 62 8 peter 2013 63 male mexico 63 9 peter 2014 63 male mexico 64 10 peter 2015 65 male mexico 65 11 sarah 2010 55 female uk 55 12 sarah 2011 55 female uk 56 13 sarah 2012 55 female uk 57 14 sarah 2013 55 female uk 58 15 sarah 2014 55 female uk 59 16 sarah 2015 60 female uk 60
关键说明
first(year)获取每个人的最早记录年份,age[year == earliest_year]提取该年份对应的初始年龄real_age = initial_age + (year - earliest_year)确保每过一年年龄自动加1,完全匹配需求- 无需对原
age列进行填充后调整,直接基于初始基准计算更准确
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

