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

求助:使用Tidyverse及基础R实现宽表转长表的两种方法

我来帮你搞定宽格式转长格式的需求,同时修复你使用基础Rreshape()函数时碰到的错误。下面分别给出两种实现方案:

方法一:使用Tidyverse的pivot_longer()

这是tidyverse生态里最直观的宽转长工具,代码简洁易读:

# 先加载tidyverse包
library(tidyverse)

# 定义原始数据框
df2 <- data.frame(name = c("John", "Anna", "Jonte"), 
                  Matematyka = c(2, 3, 5), 
                  Polski = c(5, 5, 4))

# 宽转长并替换科目名称
df_long_tidy <- df2 %>%
  pivot_longer(cols = -name,  # 选中除name外的所有列作为要转换的列
               names_to = "subject",  # 原列名存入subject列
               values_to = "mark") %>%  # 原列值存入mark列
  mutate(subject = recode(subject,  # 替换科目名称为你期望的英文
                          Matematyka = "math",
                          Polski = "eng"))

# 查看结果
print(df_long_tidy)

运行后会得到你想要的结果:

# A tibble: 6 × 3
  name  subject  mark
  <chr> <chr>   <dbl>
1 John  math        2
2 John  eng         5
3 Anna  math        3
4 Anna  eng         5
5 Jonte math        5
6 Jonte eng         4
方法二:基础R的reshape()函数(修复你的错误)

你之前的错误出在**v.names参数不能传列表**,而且没有指定timevar和times来定义转换后的科目名称。正确的用法如下:

# 定义原始数据框
df2 <- data.frame(name = c("John", "Anna", "Jonte"), 
                  Matematyka = c(2, 3, 5), 
                  Polski = c(5, 5, 4))

# 正确使用reshape()宽转长
df_long_base <- reshape(df2,
                        direction = "long",
                        varying = 2:3,  # 指定要转换的列(第2到第3列)
                        v.names = "mark",  # 存储数值的列名(单个字符串,不是列表)
                        idvar = "name",  # 分组的标识列
                        timevar = "subject",  # 存储原列名的新列名
                        times = c("math", "eng"),  # 替换原列名的自定义科目名称
                        new.row.names = 1:6)  # 重置行号

# 调整列顺序(和你期望的结果一致)
df_long_base <- df_long_base[, c("name", "subject", "mark")]

# 查看结果
print(df_long_base)

运行后输出:

name subject mark
1   John    math    2
2   Anna    math    3
3  Jonte    math    5
4   John     eng    5
5   Anna     eng    5
6  Jonte     eng    4

错误原因解释

你之前的代码里v.names = list("subject","mark")是错误的:reshape()中v.names是用来指定数值列的名称,而原列名的存储是通过timevar和times来控制的,不需要把subject放在v.names里,这才导致了invalid 'type' (list) of argument的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:31:57