You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 23:01:03