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

如何为单个变量的每个值新增列以重塑数据?不会用dplyr等工具

用dplyr + tidyr 完成数据重塑(添加cat2列)

别担心,这种数据重塑的需求在R里用dplyr生态的工具很容易搞定!我先给你一个通用的解决方案,再结合常见的例子演示,你可以根据自己的实际数据调整。

核心思路

通常这类需求是宽表转长表(或反过来的长转宽),再通过匹配规则添加cat2列。我们主要用到tidyr::pivot_longer()(宽转长)/pivot_wider()(长转宽),再配合dplyr::mutate()和dplyr::case_when()来映射cat2的取值。

示例演示(宽表转长表+添加cat2)

假设你的原数据是这样的宽表(包含id和不同cat1对应的数值):

library(dplyr)
library(tidyr)

# 原数据示例
original_df <- tibble(
  id = c(1, 2, 3),
  cat1_apple = c(5, 7, 9),
  cat1_banana = c(10, 12, 14),
  cat1_orange = c(15, 17, 19)
)

你的目标数据需要把cat1_xxx拆分成cat1列,再给每个cat1值匹配对应的cat2(比如apple对应fruit_a,banana对应fruit_b):

步骤1:宽表转长表,拆分出cat1列

先用pivot_longer()把宽表转成长表,同时提取cat1的真实取值:

long_df <- original_df %>%
  pivot_longer(
    cols = starts_with("cat1_"), # 选择所有以cat1_开头的列
    names_to = "cat1", # 列名存入cat1列
    names_prefix = "cat1_", # 去掉前缀"cat1_"
    values_to = "value" # 数值存入value列
  )

步骤2:添加cat2列

用case_when()给不同的cat1值匹配对应的cat2:

target_df <- long_df %>%
  mutate(
    cat2 = case_when(
      cat1 == "apple" ~ "fruit_a",
      cat1 == "banana" ~ "fruit_b",
      cat1 == "orange" ~ "fruit_c",
      TRUE ~ "unknown" # 处理未匹配到的特殊情况
    )
  )

最终得到的target_df就是你想要的格式:

# A tibble: 9 × 4
     id cat1   value cat2   
  <dbl> <chr>  <dbl> <chr>  
1     1 apple      5 fruit_a
2     1 banana    10 fruit_b
3     1 orange    15 fruit_c
4     2 apple      7 fruit_a
5     2 banana    12 fruit_b
6     2 orange    17 fruit_c
7     3 apple      9 fruit_a
8     3 banana    14 fruit_b
9     3 orange    19 fruit_c

进阶技巧:用映射表匹配cat2

如果cat1的取值很多,写一堆case_when会很麻烦,你可以先做一个映射表,再用left_join()来匹配:

# 提前定义cat1和cat2的映射关系
cat_mapping <- tibble(
  cat1 = c("apple", "banana", "orange"),
  cat2 = c("fruit_a", "fruit_b", "fruit_c")
)

# 关联映射表得到cat2
target_df <- long_df %>%
  left_join(cat_mapping, by = "cat1")

如果是长表转宽表的情况

如果你的原数据是长表,需要转成宽表并添加cat2,逻辑类似:

# 原长表示例
original_long <- tibble(
  id = c(1,1,2,2),
  cat1 = c("a","b","a","b"),
  value = c(10,20,15,25)
)

# 转宽表+添加cat2
target_wide <- original_long %>%
  mutate(
    cat2 = case_when(cat1 == "a" ~ "x", cat1 == "b" ~ "y")
  ) %>%
  pivot_wider(
    id_cols = c(id, cat2),
    names_from = cat1,
    values_from = value
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:05:07