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

如何在R中重塑含大量NA的Data Frame:按ID合并观测

解决思路与代码实现

先构造测试数据方便复现:

df <- data.frame(
  id = c(1,1,2,2,2,3,3),
  var1 = c(NA, 0.8, 0.7, NA, NA, NA, NA),
  var2 = c(0.4, NA, NA, 0.5, NA, 0.5, NA),
  var3 = c(NA, NA, NA, NA, 0.1, NA, 0.2)
)

方法一:dplyr 分组汇总

按id分组后,对每个变量提取唯一的非NA值。因为每个id下每个变量仅一个有效值,用max()(带na.rm=TRUE)或first(na.rm=TRUE)均可:

library(dplyr)

df_cleaned <- df %>%
  group_by(id) %>%
  summarize(
    var1 = if(all(is.na(var1))) NA else max(var1, na.rm = TRUE),
    var2 = if(all(is.na(var2))) NA else max(var2, na.rm = TRUE),
    var3 = if(all(is.na(var3))) NA else max(var3, na.rm = TRUE),
    .groups = "drop"
  )

注:加if(all(is.na(...)))是为了避免全NA变量返回-Inf,保证结果用NA填充。

方法二:data.table 高效处理

用data.table按id分组,直接提取每个变量的非NA值:

library(data.table)

setDT(df)
df_cleaned <- df[, lapply(.SD, function(x) x[!is.na(x)]), by = id]

每个变量每个id仅一个非NA值,lapply会自动提取并补全长度,得到目标格式。

方法三:tidyr pivot_wider 正确用法

你之前可能未设置values_fn参数,正确写法如下:

library(tidyr)

# 先转长格式过滤NA,再转回宽格式
df_long <- df %>%
  pivot_longer(cols = starts_with("var"), names_to = "variable", values_to = "value", values_drop_na = TRUE)

df_cleaned <- df_long %>%
  pivot_wider(names_from = "variable", values_from = "value")

也可一步完成:

df_cleaned <- df %>%
  pivot_wider(
    id_cols = id,
    names_from = everything(),
    values_from = starts_with("var"),
    values_fn = function(x) x[!is.na(x)],
    values_fill = NA
  )

三种方法均可得到你需要的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:55:20