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

R语言:如何按不同列名重塑DataFrame至指定格式?

将特定格式的R语言DataFrame转换为目标宽格式

原始数据

首先定义并查看原始DataFrame:

a <- data.frame(list(X1=c("stn", "s1", "stn", "s2"), 
  X2=c("var1", "1", "var4", "2"), 
  X3=c("var2", "2", "var3", "3"), 
  X4=c("NA", "NA", "var2", "2")))

输出结果:

X1   X2   X3   X4
1 stn var1 var2   NA
2  s1    1    2   NA
3 stn var4 var3 var2
4  s2    2    3    2

目标格式

期望转换后的DataFrame定义及输出:

b <- data.frame(list(stn=c("s1", "s2"), 
  var1=c(1, NA), 
  var2=c(2, 2), 
  var3=c(NA, 3), 
  var4=c(NA, 2)))

输出结果:

stn var1 var2 var3 var4
1  s1    1    2   NA   NA
2  s2   NA    2    3    2

解决方案

方法一:使用tidyverse工具包

通过长格式转换、分组处理实现,逻辑清晰易读:

library(tidyverse)

# 为每一组(站点+变量行)添加分组标识
a <- a %>% mutate(group = rep(1:(nrow(.)/2), each = 2))

# 整理变量名与对应值的映射关系
temp_df <- a %>%
  pivot_longer(cols = X2:X4, names_to = "col", values_to = "val") %>%
  group_by(group) %>%
  # 提取变量名并向下填充到对应的值行
  mutate(var = ifelse(X1 == "stn", val, NA),
         value = ifelse(X1 != "stn", val, NA)) %>%
  fill(var, .direction = "down") %>%
  # 过滤无效行,处理字符串NA为真实NA并转换数据类型
  filter(!is.na(value)) %>%
  select(group, var, value) %>%
  mutate(value = ifelse(value == "NA", NA, value)) %>%
  type.convert(as.is = TRUE)

# 转换为宽格式并调整列顺序
final_df <- temp_df %>%
  pivot_wider(names_from = var, values_from = value) %>%
  mutate(stn = paste0("s", group)) %>%
  select(stn, everything()) %>%
  select(-group)

print(final_df)

方法二:基础R实现

不依赖第三方包,用基础矩阵/列表操作完成:

# 分离变量名行和对应的值行
var_rows <- a[a$X1 == "stn", -1]
val_rows <- a[a$X1 != "stn", -1]

# 提取每个站点的有效变量和对应值(排除"NA")
site_vars <- apply(var_rows, 1, function(x) x[x != "NA"])
site_vals <- apply(val_rows, 1, function(x) x[x != "NA"])

# 获取所有出现过的变量
all_vars <- unique(unlist(site_vars))

# 初始化结果DataFrame
final_df <- data.frame(stn = a$X1[a$X1 != "stn"])

# 为每个变量填充对应站点的值
for (var in all_vars) {
  final_df[[var]] <- sapply(1:length(site_vars), function(i) {
    match_idx <- which(site_vars[[i]] == var)
    if (length(match_idx) > 0) {
      val <- site_vals[[i]][match_idx]
      if (val == "NA") NA else as.numeric(val)
    } else {
      NA
    }
  })
}

# 调整列顺序与目标一致
final_df <- final_df[, c("stn", "var1", "var2", "var3", "var4")]

print(final_df)

两种方法最终都会输出符合要求的DataFrame。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:20:36