R语言按ID分组合并数据行 填充非NA值保留同组字段
实现方案
核心处理逻辑按字段属性拆分,按ID分组后分别聚合即可,无需复杂的行合并操作:
- 对同组取值完全一致的公共字段(
Date、N_Date、type),分组后直接取组内第一个值 - 对
Var1~Var4字段,分组后取组内第一个非NA值,刚好适配数据中“每行Var类字段最多1个非NA值”的特征,自动把分散在不同行的有效值合并到同一行,不会出现值冲突
Python(pandas 环境)
import pandas as pd import numpy as np # 按ID分组执行聚合 res = df.groupby("ID", as_index=False).agg( # 公共字段取组内首值 Date=("Date", "first"), N_Date=("N_Date", "first"), type=("type", "first"), # Var字段取组内首个非NA值 Var1=("Var1", lambda s: s.dropna().iloc[0] if not s.dropna().empty else np.nan), Var2=("Var2", lambda s: s.dropna().iloc[0] if not s.dropna().empty else np.nan), Var3=("Var3", lambda s: s.dropna().iloc[0] if not s.dropna().empty else np.nan), Var4=("Var4", lambda s: s.dropna().iloc[0] if not s.dropna().empty else np.nan) ) # 调整列顺序与原数据集完全一致 res = res[df.columns]
说明:已将Var4调整为字符串类型的前提下,上述写法不会触发类型转换错误。若使用pandas 1.1.0及以上版本,Var字段可直接使用
"first"作为聚合函数,内置逻辑会自动跳过NA值取首个有效值,无需自定义lambda函数。
R(dplyr 环境)
library(dplyr) res <- df %>% group_by(ID) %>% summarise( # 公共字段取组内首值 Date = first(Date), N_Date = first(N_Date), type = first(type), # Var字段取组内首个非NA值 Var1 = first(na.omit(Var1)), Var2 = first(na.omit(Var2)), Var3 = first(na.omit(Var3)), Var4 = first(na.omit(Var4)), .groups = "drop" ) %>% # 调整列顺序与原数据集完全一致 select(all_of(colnames(df)))
注意事项
- 两种方案输出结果的列数、列名、字段类型均与原数据集保持一致,每个ID仅对应1行记录
- 基于给出的数据特征(同ID公共字段取值完全一致、单Var字段同组最多1个非NA值),聚合过程不会出现有效值覆盖、类型不匹配的问题
内容的提问来源于stack exchange,提问作者Aisberg
相关产品推荐
相关产品推荐

