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

基于中点假设逐年累加技能字符串的R语言实现方案

问题描述

我有一份人员-技能及对应技能使用年份的数据集,希望基于「技能获取于两次使用的中点」这一假设,填充年份区间内的技能信息。对base R、tidyverse或data.table工具无偏好。

现有数据集:

have <- data.frame(
  person = c("A","A","B","B","C","C"),
  skill = c("S1","S2", "S1,S2","S3","S1,S3","S1,S2" ),
  year = c(2015,2018,2016,2018,2016,2018)
)

期望得到的数据集:

want <- data.frame(
  person = c("A","A","A","A","B","B","B","C","C","C"),
  skill = c("S1","S1","S1,S2","S1,S2","S1,S2","S1,S2,S3","S1,S2,S3","S1,S3","S1,S2,S3","S1,S2,S3"),
  year = c(2015,2016,2017,2018,2016,2017,2018,2016,2017,2018)
)

我尝试过用fill(.direction = "down"),但不知道如何反向填充技能,也不清楚怎么对已拥有的技能去重。


解决方案(tidyverse实现)

核心思路是先拆分技能为单个条目,确定每个技能的生效起始年份,再按年份聚合所有生效技能,最后合并成字符串:

library(tidyverse)

result <- have %>%
  # 1. 把逗号分隔的技能拆成单独行
  separate_rows(skill, sep = ",") %>%
  # 2. 按人员分组,为每个技能计算生效起始年份(两次记录的中点向上取整)
  group_by(person, skill) %>%
  mutate(
    start_year = ifelse(n() > 1, ceiling((year + lead(year))/2), year)
  ) %>%
  ungroup() %>%
  # 3. 按人员生成所有需要的连续年份序列
  group_by(person) %>%
  reframe(
    year = seq(min(year), max(year), by = 1),
    skill = skill,
    start_year = start_year
  ) %>%
  # 4. 筛选出当前年份已生效的技能
  filter(year >= start_year) %>%
  # 5. 按人员和年份聚合技能,去重后用逗号连接
  group_by(person, year) %>%
  summarise(skill = str_c(sort(unique(skill)), collapse = ","), .groups = "drop")

# 查看结果
print(result)

关键步骤说明

  • 拆分技能:separate_rows将多技能条目拆分为单技能行,便于逐个处理技能的生效时间。
  • 计算起始年:对有两次记录的技能,取两次年份的中点向上取整作为技能获取时间;仅一次记录的技能,从记录年份开始生效。
  • 生成完整年份:为每个人生成从最早到最晚记录年份的所有连续年份,确保无遗漏。
  • 筛选生效技能:保留当前年份大于等于技能起始年的条目,符合「中点获取技能」的假设。
  • 聚合去重:按人员和年份分组,对技能去重、排序后合并为逗号分隔的字符串,与期望结果完全匹配。

内容的提问来源于stack exchange,提问作者Torin McFarland

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:06:25