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

R语言堆叠同类变量实现数据集宽表转长表的方法

R 批量按3个变量为一组堆叠宽表转长表方案

问题描述

我有一个大型数据集的部分变量,其中每3个连续变量属于同一测量维度:例如前3个变量c_0064、c_0065、c_0066记录受访者知晓的3个品牌,第二组3个变量v_159_1、v_159_2、v_159_3记录受访者对前述3个品牌的态度,以此类推。仅展示数据集的首尾列,v_159_3之后实际依次为v_160_1、v_160_2、v_160_3、v_161_1……直至v_182_1、v_182_2、v_182_3。

数据集结构示例

structure(list(lfdn = c(4, 6, 7, 8, 9, 11, 12, 19), c_0064 = c("x", "t", "x", "x", "t", "x", "z", "z"), c_0065 = c("z", "z", "z", "f", "f", "f", "t", "t"), c_0066 = c("x", "x", "x", "a", "f", "t", "z", "b"), v_159_1 = c(1, 1, 3, 2, 2, 5, 4, 3), v_159_2 = c(3, 3, 3, 3, 3, 2, 5, 1), v_159_3 = c(5, 5, 1, 4, 4, 1, 2, 2), v_182_1 = c(1, 1, 5, 5, 4, 4, 4, 4), v_182_2 = c(4, 2, 2, 2, 2, 3, 1, 5), v_182_3 = c(5, 4, 5, 1, 2, 5, 2, 2)), row.names = c(NA, -8L), class = c("tbl_df", "tbl", "data.frame"))

> df
# A tibble: 8 x 10
   lfdn c_0064 c_0065 c_0066 v_159_1 v_159_2 v_159_3 v_182_1 v_182_2 v_182_3
  <dbl> <chr>  <chr>  <chr>    <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1     4 x      z      x            1       3       5       1       4       5
2     6 t      z      x            1       3       5       1       2       4
3     7 x      z      x            3       3       1       5       2       5
4     8 x      f      a            2       3       4       5       2       1
5     9 t      f      f            2       3       4       4       2       2
6    11 x      f      t            5       2       1       4       3       5
7    12 z      t      z            4       5       2       4       1       2
8    19 z      t      b            3       1       2       4       5       2

预期输出格式

structure(list(lfdn = c(4, 6, 7, 8, 9, 11, 12, 19, 4, 6, 7, 8, 9, 11, 12, 19, 4, 6, 7, 8, 9, 11, 12, 19), c_0064_65_66 = c("x", "t", "x", "x", "t", "x", "z", "z", "z", "z", "z", "f", "f", "f", "t", "t", "x", "x", "x", "a", "f", "t", "z", "b"), v_159_1_2_3 = c(1, 1, 3, 2, 2, 5, 4, 3, 3, 3, 3, 3, 3, 2, 5, 1, 5, 5, 1, 4, 4, 1, 2, 2), v_181_1_2_3 = c(1, 1, 5, 5, 4, 4, 4, 4, 4, 2, 2, 2, 2, 3, 1, 5, 5, 4, 5, 1, 2, 5, 2, 2)), row.names = c(NA, -24L), class = c("tbl_df", "tbl", "data.frame"))

> dflong
# A tibble: 24 x 4
    lfdn c_0064_65_66 v_159_1_2_3 v_181_1_2_3
   <dbl> <chr>              <dbl>       <dbl>
 1     4 x                      1           1
 2     6 t                      1           1
 3     7 x                      3           5
 4     8 x                      2           5
 5     9 t                      2           4
 6    11 x                      5           4
 7    12 z                      4           4
 8    19 z                      3           4
 9     4 z                      3           4
10     6 z                      3           2
# ... with 14 more rows

现有问题

尝试使用melt处理数据失败了,目前能想到的方法是使用stack命令逐组处理3个变量,例如stack(df, select=c("c_0064", "c_0065", "c_0066")),最后再把所有堆叠后的变量合并。但除了展示的变量外,数据集还有大量重复组变量,需要更高效的实现方法。


解决方案

使用tidyverse的pivot_longer函数可以实现批量自动处理,不需要逐组写代码,中间的v_160到v_181所有组都会自动识别转换:

library(tidyverse)

dflong <- df %>%
  # 统一品牌列命名规则,和态度列的 组名_位次 格式对齐
  rename_with(
    ~ str_replace(., "c_0064", "c_006_1") %>%
      str_replace("c_0065", "c_006_2") %>%
      str_replace("c_0066", "c_006_3"),
    .cols = starts_with("c_006")
  ) %>%
  # 宽转长,按组自动拆分堆叠
  pivot_longer(
    cols = -lfdn,
    names_to = c(".value", "item_seq"),
    names_sep = "_(?=\\d$)" # 匹配最后一个下划线,分隔组名和对应品牌的位次
  ) %>%
  # 按受访者ID和品牌位次排序,和预期输出顺序完全一致
  arrange(lfdn, item_seq) %>%
  # 修改列名为你需要的格式
  rename(
    c_0064_65_66 = c_006,
    v_159_1_2_3 = v_159,
    v_182_1_2_3 = v_182
  ) %>%
  # 不需要位次列可直接删除
  select(-item_seq)

如果需要保留所有中间v组的原始组名,不需要手动写rename规则,直接去掉rename步骤即可,函数会自动生成v_160、v_161等列名,也可以根据需求批量修改列名。


内容的提问来源于stack exchange,提问作者Nadine M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:36:01