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

使用tidyverse将长格式转宽格式时遇问题求助

解决pivot_wider转换长表到宽表时的重复值警告与列表列问题

问题重现

用户尝试用tidyverse的pivot_wider将长格式数据转宽格式,代码如下:

library(tidyverse)

df <- data.frame(continent = c("europe", "africa"),
                 region = c("north", "west", "south"),
                 number = 1:18)

df_long <- df |>
  pivot_wider(names_from = region,
              values_from = number)

运行后出现警告及错误,输出为列表列:

Warning message:
Values from number are not uniquely identified; output will contain list-cols.
• Use values_fn = list to suppress this warning.
• Use values_fn = {summary_fun} to summarise duplicates.
• Use the following dplyr code to identify duplicates.
{data} %>%
dplyr::group_by(continent, region) %>%
dplyr::summarise(n = dplyr::n(), .groups = "drop") %>%
dplyr::filter(n > 1L)
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) :
invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) :
attempt to use zero-length variable name

head(df_long)

A tibble: 2 × 4

continent north west south

1 europe <int [3]> <int [3]> <int [3]>
2 africa <int [3]> <int [3]> <int [3]>

问题原因

首先看数据构造:continent只有2个值,region有3个值,number是1:18,这意味着continent和region的组合会重复3次(2*3=6组,18/6=3)。pivot_wider要求每行的names_from与values_from的对应组合必须唯一,否则无法将多个值塞进单个单元格,只能用列表列存储,同时触发重复值警告。

报错信息里的invalid first argument和zero-length variable name是RStudio缓存的小问题,核心矛盾还是重复值导致的列表列输出。

解决方案

根据需求不同,有三种常见处理方式:

1. 保留所有重复值,添加唯一标识符

如果要保留所有number值,先给每个continent-region分组添加序号,让continent+region+id成为唯一组合:

df |>
  group_by(continent, region) |>
  mutate(id = row_number()) |> # 给每组添加行序号
  ungroup() |>
  pivot_wider(names_from = region,
              values_from = number)

输出示例:

# A tibble: 6 × 4
  continent    id north  west south
  <chr>     <int> <int> <int> <int>
1 europe        1     1     4     7
2 europe        2     2     5     8
3 europe        3     3     6     9
4 africa        1    10    13    16
5 africa        2    11    14    17
6 africa        3    12    15    18

2. 对重复值进行汇总

如果不需要保留所有值,可对每个continent-region组合的number做汇总(求和、均值、最大/最小值等),用values_fn指定汇总函数:

# 求和示例
df |>
  pivot_wider(names_from = region,
              values_from = number,
              values_fn = sum)

输出:

# A tibble: 2 × 4
  continent north  west south
  <chr>     <int> <int> <int>
1 europe        6    15    24
2 africa       33    42    51

其他汇总函数如mean、max、min可直接替换sum使用。

3. 仅保留每个组合的第一个值

如果只需要每个continent-region组合的第一个值,用values_fn = first:

df |>
  pivot_wider(names_from = region,
              values_from = number,
              values_fn = first)

输出:

# A tibble: 2 × 4
  continent north  west south
  <chr>     <int> <int> <int>
1 europe        1     4     7
2 africa       10    13    16

内容的提问来源于stack exchange,提问作者always.learning

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:23:13