You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在R语言中重塑含多列的重复ID数据集

R语言多列数据集重塑解决方案

嘿,我来帮你搞定这个R里的数据重塑问题!先结合你描述的数据集结构,我先模拟一个贴近你场景的示例数据,然后给出几种常见重塑需求的解决方案,你可以根据自己的实际目标调整。

先模拟你的数据集结构

首先用代码生成一个和你描述匹配的样例数据,方便你对照测试:

set.seed(123) # 保证结果可复现
df <- data.frame(
  Id = rep(c("A", "B", "C"), each = 3), # 每个Id重复3次(对应3年)
  Start_Year = rep(c(2020, 2019, 2021), each = 3), # 每个Id的起始年份重复
  Year = c(2020, 2021, 2022, 2019, 2020, 2021, 2021, 2022, 2023), # 每条记录的年份
  Location = sample(c("Loc1", "Loc2"), 9, replace = TRUE), # 仅两种地点取值
  Sub_Location = c("SubA", "SubA", NA, "SubB", NA, NA, "SubC", "SubC", "SubC") # 子地点可能为NULL
)

常见重塑场景的代码方案

1. 长格式转宽格式(每个Id一行,年份作为列)

如果想把每个Id的多年数据合并成一行,用tidyr::pivot_wider()是最方便的:

library(tidyr)
library(dplyr)

wide_df <- df %>%
  pivot_wider(
    id_cols = c(Id, Start_Year), # 保留每个Id固定不变的列
    names_from = Year, # 用年份作为新列名的前缀
    values_from = c(Location, Sub_Location), # 需要展开的列
    names_sep = "_" # 列名分隔符,比如生成`Location_2020`这样的列
  )

2. 处理子地点的NULL值

如果想把每个Id的Sub_Location缺失值填充(比如用该Id最近的非空值),或者统一为该Id的第一个/最后一个非空子地点:

# 方案1:上下填充缺失的子地点值
filled_sub_loc_df <- df %>%
  group_by(Id) %>%
  fill(Sub_Location, .direction = "downup") %>% # 先向下填充,再向上填充覆盖所有缺失
  ungroup()

# 方案2:统一用每个Id的第一个非空子地点值
fixed_sub_loc_df <- df %>%
  group_by(Id) %>%
  mutate(Sub_Location = first(na.omit(Sub_Location))) %>% # 提取第一个非空值替换所有
  ungroup()

3. 按地点分组聚合数据

如果需要按Location统计年度数据(比如每个地点每年的唯一Id数量):

aggregated_df <- df %>%
  group_by(Location, Year) %>%
  summarise(
    Unique_Id_Count = n_distinct(Id),
    Avg_Start_Year = mean(Start_Year),
    .groups = "drop" # 取消分组,返回普通数据框
  )

4. 宽格式转长格式(如果你的原始数据是宽格式,需要转成你描述的长格式)

如果你的数据原本是宽格式(比如每个Id一行,年份列是分散的),可以用pivot_longer()转成长格式:

# 先模拟一个宽格式示例
wide_example <- data.frame(
  Id = c("A", "B"),
  Start_Year = c(2020, 2019),
  Location_2020 = "Loc1",
  Location_2021 = "Loc2",
  Sub_Location_2020 = "SubA",
  Sub_Location_2021 = NA
)

# 转成长格式
long_df <- wide_example %>%
  pivot_longer(
    cols = matches("(Location|Sub_Location)_\\d{4}"), # 匹配带年份的列
    names_to = c(".value", "Year"), # .value保留原列名前缀,Year提取年份
    names_pattern = "(.*)_(\\d{4})" # 用正则拆分列名的前缀和年份
  ) %>%
  mutate(Year = as.integer(Year)) # 把年份转成整数类型

如果你的重塑需求更具体(比如要输出特定结构的数据集),可以补充细节后再调整方案哦~

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

火山引擎 最新活动