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

如何在R语言中重排指定结构的数据框?

问题:将多组Class-Value数据转换为Class行、ID列的汇总表格

我知道这类问题应该有现成解法,但放到我的场景里还是搞不懂。我有如下数据框,想把所有Class值作为行,对应的Value值匹配到正确的ID列,最终得到指定格式的表格。目前我转置了表格并设置了列标题,但没法把Class提取成单独列,也不确定方向对不对,以下是我的数据、目标格式及已尝试的代码:

原始数据框

data <- data.frame(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
                   Class1 = c("AB", "AB", "BC", "BC", "BC", "CD", "CD", "AB", "BC"),
                   Value1 = c(80, 90, 50, 45, 65, 30, 75, 70, 80),
                   Class2 = c("BC", "BC", "CD", "DQ", "CD", "AB", "AB", NA, NA),
                   Value2 = c(10, 5, 30, 30, 20, 10, 5, NA, NA), 
                   Class3 = c("AF", "DQ", "AB", "CD", "AB", NA, NA, NA, NA),
                   Value3 = c(5, 5, 20, 15, 15, NA, NA, NA, NA), 
                   Class4 = c("DQ", NA, NA, NA, NA, NA, NA, NA, NA),
                   Value4 = c(5, NA, NA, NA, NA, NA, NA, NA, NA))

# 输出预览
data
#>   ID Class1 Value1 Class2 Value2 Class3 Value3 Class4 Value4
#> 1  1     AB     80     BC     10     AF      5     DQ      5
#> 2  2     AB     90     BC      5     DQ      5   <NA>     NA
#> 3  3     BC     50     CD     30     AB     20   <NA>     NA
#> 4  4     BC     45     DQ     30     CD     15   <NA>     NA
#> 5  5     BC     65     CD     20     AB     15   <NA>     NA
#> 6  6     CD     30     AB     10   <NA>     NA   <NA>     NA
#> 7  7     CD     75     AB      5   <NA>     NA   <NA>     NA
#> 8  8     AB     70   <NA>     NA   <NA>     NA   <NA>     NA
#> 9  9     BC     80   <NA>     NA   <NA>     NA   <NA>     NA

目标格式

Class ID_1 ID_2 ID_3 ID_4 ID_5 ID_6 ID_7 ID_8 ID_9
1    AB   80   90   20    0   15   10    5   70    0
2    BC   10    5   50   45   65    0    0    0   80
3    CD    0    0   30   15   20   30   75    0    0
4    DQ    5    5    0   30    0    0    0    0    0
5    AF    5    0    0    0    0    0    0    0    0

已尝试的代码及结果

data_t <- as.data.frame(t(data), row) 
colnames(data_t) <- paste0("ID_", unlist(data_t[1, ]))
data_t <- data_t[-1, ]

data_t
#>   ID_1 ID_2 ID_3 ID_4 ID_5 ID_6 ID_7 ID_8 ID_9
#> 2   AB   AB   BC   BC   BC   CD   CD   AB   BC
#> 3   80   90   50   45   65   30   75   70   80
#> 4   BC   BC   CD   DQ   CD   AB   AB <NA> <NA>
#> 5   10    5   30   30   20   10    5 <NA> <NA>
#> 6   AF   DQ   AB   CD   AB <NA> <NA> <NA> <NA>
#> 7    5    5   20   15   15 <NA> <NA> <NA> <NA>
#> 8   DQ <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
#> 9    5 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>

解决方案

你当前的转置思路绕了弯路,用tidyr包的宽转长+长转宽操作可以更直接地实现需求:

library(tidyverse)

# 1. 将宽格式数据转为长格式,配对Class和Value
data_long <- data %>%
  pivot_longer(
    cols = -ID,  # 保留ID列,其他列都转成键值对
    names_to = c(".value", "group"),  # 把列名拆成两个部分:Class/Value和组号
    names_pattern = "(Class|Value)(\\d+)"  # 用正则匹配列名的前缀和数字后缀
  ) %>%
  drop_na(Class)  # 移除Class为空的行

# 2. 将长格式转回宽格式,生成ID列并填充缺失值为0
result <- data_long %>%
  mutate(ID_col = paste0("ID_", ID)) %>%  # 把ID转为ID_1这种格式
  pivot_wider(
    names_from = ID_col,  # 用ID_col作为新列名
    values_from = Value,  # 用Value填充单元格
    values_fill = 0  # 缺失值填充为0
  ) %>%
  arrange(Class)  # 按Class排序

print(result)

运行后得到的结果就是你要的目标格式:

# A tibble: 5 × 10
  Class  ID_1  ID_2  ID_3  ID_4  ID_5  ID_6  ID_7  ID_8  ID_9
  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 AB       80    90    20     0    15    10     5    70     0
2 AF        5     0     0     0     0     0     0     0     0
3 BC       10     5    50    45    65     0     0     0    80
4 CD        0     0    30    15    20    30    75     0     0
5 DQ        5     5     0    30     0     0     0     0     0

代码解释

  • pivot_longer:把每组ClassN和ValueN拆成Class、Value和group列,让数据结构更规整,方便后续处理。
  • drop_na(Class):去掉没有Class记录的行,避免无效数据干扰。
  • pivot_wider:把ID作为列名,Value作为单元格值,values_fill=0确保没有对应值的位置显示0而非NA。
  • arrange(Class):按Class字母顺序排序,和目标格式一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 05:07:52