在R语言中如何按变量将行数据转置为列?
多变量数据转置解决方案
问题背景
现有如下格式的数据集:
dataA=data.frame(structure(list(Season = c(2021, 2021, 2021, 2021, 2021, 2022, 2022, 2022, 2022, 2022, 2023, 2023, 2023, 2023, 2023), ID = c("A", "B", "C", "D", "E", "A", "B", "C", "D", "E", "A", "B", "C", "D", "E"), S = c(44, 64, 65, 68, 58, 46, 48, 48, 62, 42, 49, 63, 75, 90, 55), Na = c(115, 131, 153, 118, 140, 127, 108, 119, 122, 139, 136, 134, 170, 139, 178), Ca = c(1.58, 2.41, 2.49, 2.25, 2.1, 1.21, 2.07, 2.66, 2.26, 1.9, 1.36, 2.18, 2.53, 2.22, 2.12)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -15L)))
数据预览:
| Season | ID | S | Na | Ca |
|---|---|---|---|---|
| 2021 | A | 44 | 115 | 1.58 |
| 2021 | B | 64 | 131 | 2.41 |
| 2021 | C | 65 | 153 | 2.49 |
| 2021 | D | 68 | 118 | 2.25 |
| 2021 | E | 58 | 140 | 2.10 |
| 2022 | A | 46 | 127 | 1.21 |
| 2022 | B | 48 | 108 | 2.07 |
| 2022 | C | 48 | 119 | 2.66 |
| 2022 | D | 62 | 122 | 2.26 |
| 2022 | E | 42 | 139 | 1.90 |
| 2023 | A | 49 | 136 | 1.36 |
| 2023 | B | 63 | 134 | 2.18 |
| 2023 | C | 75 | 170 | 2.53 |
| 2023 | D | 90 | 139 | 2.22 |
| 2023 | E | 55 | 178 | 2.12 |
需要将数据按ID分组,把Season转置为列,同时保留S、Na、Ca三个变量的对应值。尝试使用reshape::cast()时出现报错:
library(reshape) dataB= reshape::cast(dataA, ID ~ Season, value=c("S","Na", "Ca"))
报错信息:
Error in data.frame(data[, c(variables), drop = FALSE], result = data$value) : arguments imply differing number of rows: 15, 0 In addition: Warning message: In names(data) == value : longer object length is not a multiple of shorter object length
可行解决方案
方法1:使用tidyverse的pivot_wider
tidyverse生态中的pivot_wider函数专门用于宽表转换,支持多变量同时转置,语法直观:
library(tidyverse) dataB <- dataA %>% pivot_wider( id_cols = ID, # 作为分组主键的列 names_from = Season, # 需要转置为列名的变量 values_from = c(S, Na, Ca) # 需要保留值的多变量 )
转换后的结果格式:
| ID | S_2021 | S_2022 | S_2023 | Na_2021 | Na_2022 | Na_2023 | Ca_2021 | Ca_2022 | Ca_2023 |
|---|---|---|---|---|---|---|---|---|---|
| A | 44 | 46 | 49 | 115 | 127 | 136 | 1.58 | 1.21 | 1.36 |
| B | 64 | 48 | 63 | 131 | 108 | 134 | 2.41 | 2.07 | 2.18 |
| C | 65 | 48 | 75 | 153 | 119 | 170 | 2.49 | 2.66 | 2.53 |
| D | 68 | 62 | 90 | 118 | 122 | 139 | 2.25 | 2.26 | 2.22 |
| E | 58 | 42 | 55 | 140 | 139 | 178 | 2.10 | 1.90 | 2.12 |
方法2:使用data.table的dcast
如果数据集规模极大,data.table的dcast函数处理速度更快,内存效率更高:
library(data.table) # 将data.frame转换为data.table格式 setDT(dataA) dataB <- dcast( dataA, ID ~ Season, value.var = c("S", "Na", "Ca") # 指定需要转置的多变量 )
该方法得到的结果与pivot_wider完全一致,列名格式为变量名_年份,满足转置需求。
内容的提问来源于Stack Exchange,提问作者J.K Kim
相关产品推荐
相关产品推荐

