0Pricing
R Academy · 课时

使用 pivot_longer() 将宽格式转换为长格式

将宽格式表格重塑为适合分析的整洁长格式

使用 pivot_longer() 将宽格式转换为长格式 是 CoddyKit 上的免费 R Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。

宽格式与长格式数据

数据可以存储为宽格式(每个主体一行,包含多个值列),也可以存储为长格式(每条观测一行,包含一个变量名列和另一个值列)。许多用于可视化和建模的 R 软件包都要求使用长格式。

library(tidyr)
library(dplyr)

# Wide format: each quarter is a column
wide_df <- data.frame(
  student = c('Alice','Bob','Carol'),
  q1 = c(85, 90, 78),
  q2 = c(88, 85, 80),
  q3 = c(92, 88, 84)
)

print(wide_df)
cat('\nShape:', nrow(wide_df), 'rows x', ncol(wide_df), 'cols')

pivot_longer() 基础

pivot_longer(df, cols, names_to, values_to)将宽格式转换为长格式。cols 指定要透视的列,names_to 是用于存放原列名的新列,values_to 是用于存放值的新列。

library(tidyr)

wide_df <- data.frame(
  student = c('Alice','Bob','Carol'),
  q1 = c(85, 90, 78),
  q2 = c(88, 85, 80),
  q3 = c(92, 88, 84)
)

long_df <- pivot_longer(
  wide_df,
  cols = c(q1, q2, q3),
  names_to = 'quarter',
  values_to = 'score'
)

print(long_df)

使用 starts_with() 选择列

您无需明确列出列名,而可以在 cols 内使用 tidyselect 辅助函数。starts_with('prefix')、ends_with('suffix') 和 contains('string') 对于一致地透视具有相同命名模式的列尤其有用。

library(tidyr)

df <- data.frame(
  id = 1:3,
  sales_jan = c(100, 200, 150),
  sales_feb = c(120, 180, 160),
  sales_mar = c(130, 190, 170)
)

# Select all sales_ columns automatically
pivot_longer(
  df,
  cols = starts_with('sales_'),
  names_to = 'month',
  values_to = 'sales'
)

使用 -col 排除列

另一种方法是使用 -col_name 指定要从透视中排除的列。其余所有列都会被透视。当只有一两个 ID 列、却有许多值列时,这种方法很方便。

library(tidyr)

df <- data.frame(
  region = c('East','West'),
  jan = c(100, 200),
  feb = c(110, 210),
  mar = c(120, 220),
  apr = c(130, 230)
)

# Pivot everything except 'region'
pivot_longer(df, cols = -region, names_to = 'month', values_to = 'revenue')

names_prefix — 去除前缀

当列名带有类似 score_q1、score_q2 的前缀时,names_prefix 参数会从生成的 names_to 列中去除该前缀,从而保持标识符整洁。

library(tidyr)

df <- data.frame(
  id = 1:3,
  score_q1 = c(85, 90, 78),
  score_q2 = c(88, 85, 80),
  score_q3 = c(92, 88, 84)
)

pivot_longer(
  df,
  cols = starts_with('score_'),
  names_to = 'quarter',
  names_prefix = 'score_',
  values_to = 'score'
)

透视多组列

当您有多组值列(例如同时有 sales_q1 和 cost_q1)时,请在 names_to 中使用多个值,并结合 names_pattern 将列名拆分为不同部分。

library(tidyr)

df <- data.frame(
  id = 1:2,
  sales_q1 = c(100, 200),
  sales_q2 = c(110, 210),
  cost_q1 = c(60, 110),
  cost_q2 = c(65, 115)
)

pivot_longer(
  df,
  cols = -id,
  names_to = c('.value', 'quarter'),
  names_pattern = '(.+)_(q[0-9]+)'
)

names_transform — 转换类型

默认情况下,新名称列的类型为字符型。使用 names_transform 可以自动将名称列转换为其他类型(例如,将 y2020、y2021 等列名转换为整数年份)。

library(tidyr)

df <- data.frame(
  product = c('A','B'),
  y2021 = c(100, 200),
  y2022 = c(110, 210),
  y2023 = c(120, 220)
)

result <- pivot_longer(
  df,
  cols = -product,
  names_to = 'year',
  names_prefix = 'y',
  names_transform = list(year = as.integer),
  values_to = 'sales'
)

print(result)
cat('year column type:', class(result$year))

values_drop_na — 删除缺失值

当宽格式中某些列与行的组合存在缺失值时,它们在长格式中会显示为 NA。设置 values_drop_na = TRUE,即可自动删除值为 NA 的行。

library(tidyr)

df <- data.frame(
  student = c('Alice','Bob','Carol'),
  q1 = c(85, NA, 78),
  q2 = c(88, 85, NA),
  q3 = c(NA, 88, 84)
)

# Without drop: 9 rows including NAs
pivot_longer(df, -student, names_to='quarter', values_to='score',
             values_drop_na = TRUE)

长格式让 ggplot2 更易使用

转换为长格式最重要的原因是:ggplot2 会从列中映射图形美学属性。当所有值位于一列、类别位于另一列时,您就可以轻松使用 color = quarter 或 facet_wrap(~quarter)。

library(tidyr)
# (ggplot2 not run here, but showing the data preparation)

df <- data.frame(
  month = c('Jan','Feb','Mar'),
  product_A = c(100, 120, 110),
  product_B = c(200, 190, 210)
)

# After pivoting, ready for ggplot2:
long_df <- pivot_longer(df, -month, names_to='product', values_to='sales')
print(long_df)
# ggplot(long_df, aes(x=month, y=sales, color=product)) + geom_line()

透视数值列名

有时列名是纯数字(例如年份:2020、2021)。在 R 中,数据框中的数值列名需要加引号。请在 cols 参数中使用 num_range('', 2020:2023) 或反引号引起来的列名来处理它们。

library(tidyr)

# Year columns as numbers (common in census-style data)
df <- data.frame(
  country = c('US','UK'),
  '2021' = c(100, 80),
  '2022' = c(110, 85),
  '2023' = c(120, 90),
  check.names = FALSE
)

pivot_longer(
  df,
  cols = c('2021','2022','2023'),
  names_to = 'year',
  values_to = 'gdp_index'
)

比较透视结果

透视后请验证结果:行数应为 nrow(wide) * n_pivoted_cols,而 names_to 列中的唯一值应与原始列名一致(如果去除了前缀,则不包括该前缀)。

library(tidyr)

wide <- data.frame(
  id = 1:4,
  jan = c(10,20,30,40),
  feb = c(11,21,31,41),
  mar = c(12,22,32,42)
)

long <- pivot_longer(wide, -id, names_to='month', values_to='value')

cat('Wide rows:', nrow(wide), '\n')
cat('Long rows:', nrow(long), '(expected', nrow(wide)*3, ')\n')
cat('Months:', paste(unique(long$month), collapse=', '), '\n')

快速检查

names_prefix 参数在 pivot_longer() 中的作用是什么?

回顾:pivot_longer()

将宽格式转换为长格式的要点:

  • pivot_longer(df, cols, names_to, values_to) 是核心函数
  • cols 接受 tidyselect:starts_with()、-id_col、c('a','b')
  • names_prefix 去除列名开头的字符串
  • names_transform 转换名称列的类型(例如转换为整数)
  • values_drop_na = TRUE 自动删除包含 NA 的行
  • 长格式是 ggplot2、大多数建模函数和统计检验所要求的格式
  • 验证方式:长格式行数 = 宽格式行数 × 透视列数
library(tidyr)

df <- data.frame(
  team = c('Alpha','Beta'),
  sales_2022 = c(100, 200),
  sales_2023 = c(120, 220),
  sales_2024 = c(140, 240)
)

pivot_longer(
  df,
  cols = starts_with('sales_'),
  names_to = 'year',
  names_prefix = 'sales_',
  names_transform = list(year = as.integer),
  values_to = 'revenue'
)

常见问题解答

「使用 pivot_longer() 将宽格式转换为长格式」课时是免费的吗?

是的 — 「使用 pivot_longer() 将宽格式转换为长格式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。

「使用 pivot_longer() 将宽格式转换为长格式」这节课中我会学到什么?

将宽格式表格重塑为适合分析的整洁长格式 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 R Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「使用 pivot_longer() 将宽格式转换为长格式」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 R Academy 课中编写并运行代码吗?

能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 pivot_longer() 将宽格式转换为长格式
  2. 使用 pivot_wider() 将长格式转换为宽格式
  3. 使用 separate() 和 unite() 处理字符串列
  4. 嵌套与展开数据框
← 返回 R Academy