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

R语言宽格式数据转长格式:如何转换指定结构数据集得到目标长表

R语言宽格式转指定长格式代码调整方案

错误原因

你两次调用gather时没有将相同编号的LOC和OFF字段做匹配,不同编号的字段交叉组合产生了大量冗余数据,是多余行出现的核心原因。

推荐方案:使用tidyr的pivot_longer实现(官方已推荐用该函数替代旧版gather)

pivot_longer支持直接匹配列名中的分组信息,一步完成转换,代码更简洁不易出错:

# 加载依赖包
library(tidyverse)

# 原始数据
example <- data.frame(RTD_1_LOC = c('A', 'B'), RTD_2_LOC = c('C', 'D'),
                      RTD_3_LOC = c('E', 'F'), RTD_4_LOC = c('G', 'H'),
                      RTD_5_LOC = c('I', 'J'),RTD_1_OFF = c('1', '2'), RTD_2_OFF = c('3', '4'),
                      RTD_3_OFF = c('5', '6'), RTD_4_OFF = c('7', '8'),
                      RTD_5_OFF = c('9', '10'))

# 一步转换为目标格式
example2 <- example %>%
  pivot_longer(
    cols = everything(), # 选择所有列参与转换
    # 正则匹配列名规则:RTD_【数字】_【LOC/OFF】
    names_pattern = "RTD_(\\d+)_(LOC|OFF)",
    # 第一部分匹配结果存为RTD列,第二部分匹配的字段类型作为新列名,对应值存入对应列
    names_to = c("RTD", ".value")
  ) %>%
  mutate(RTD = as.integer(RTD), OFF = as.integer(OFF)) # 转换为目标要求的数值格式

运行后得到的example2和你给出的目标结构完全一致。

原gather写法的修正方案

如果你需要沿用gather的写法,需要增加匹配相同RTD编号的逻辑避免交叉冗余:

library(tidyverse)
# 转换LOC字段
ex_loc <- gather(example, key = "rtd_key", value = "LOC", RTD_1_LOC:RTD_5_LOC) %>%
  mutate(RTD = as.integer(sub("RTD_(\\d+)_LOC", "\\1", rtd_key))) %>%
  select(-rtd_key)

# 转换OFF字段
ex_off <- gather(example, key = "rtd_key", value = "OFF", RTD_1_OFF:RTD_5_OFF) %>%
  mutate(RTD = as.integer(sub("RTD_(\\d+)_OFF", "\\1", rtd_key))) %>%
  select(-rtd_key)

# 按RTD和原始行号匹配拼接
example2 <- ex_loc %>%
  group_by(RTD) %>%
  mutate(rowid = row_number()) %>%
  left_join(ex_off %>% group_by(RTD) %>% mutate(rowid = row_number()),
            by = c("RTD", "rowid")) %>%
  ungroup() %>%
  select(-rowid) %>%
  mutate(OFF = as.integer(OFF))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 05:06:01