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

如何用tidyverse在R中将竖线分隔列表转为长格式?

R数据框拆分与格式转换解决方案

原始数据

foo <- data.frame(x=c(1,2,3), y=c("a", "b|c", "d|e|f"))
foo
#   x     y
# 1 1     a
# 2 2   b|c
# 3 3 d|e|f

需求1:转换为长格式

目标输出:

foo_long <- data.frame(x=c(1,2,2,3,3,3), y=c("a", "b", "c", "d", "e", "f"))
foo_long
#   x y
# 1 1 a
# 2 2 b
# 3 2 c
# 4 3 d
# 5 3 e
# 6 3 f

当前进度

已通过str_split将y列拆分为列表列,但未展开:

foo_long <- foo %>% mutate(y=str_split(y, "\\|"))
foo_long
#   x       y
# 1 1       a
# 2 2    b, c
# 3 3 d, e, f
str(foo_long)
# 'data.frame':   3 obs. of  2 variables:
#  $ x: num  1 2 3
#  $ y:List of 3
#   ..$ : chr "a"
#   ..$ : chr  "b" "c"
#   ..$ : chr  "d" "e" "f"

实现方法

方法1:tidyverse管道式实现

使用tidyr::unnest()直接展开列表列:

library(tidyr)
library(dplyr)

foo_long <- foo %>% 
  mutate(y = str_split(y, "\\|")) %>% 
  unnest(y)

方法2:基础R实现

通过重复x值+拆分展开y值:

y_split <- strsplit(foo$y, "\\|")
foo_long <- data.frame(
  x = rep(foo$x, sapply(y_split, length)),
  y = unlist(y_split)
)

需求2:转换为二进制宽格式(补充需求)

目标输出:

foo_long2 <- data.frame(x=c(1,2,3),
                        a=c(1,0,0), b=c(0,1,0), c=c(0,1,0),
                        d=c(0,0,1), e=c(0,0,1), f=c(0,0,1))
foo_long2
#   x a b c d e f
# 1 1 1 0 0 0 0 0
# 2 2 0 1 1 0 0 0
# 3 3 0 0 0 1 1 1

实现方法

方法1:tidyverse管道式实现

先转长格式,再用pivot_wider生成二进制列:

foo_long2 <- foo %>% 
  mutate(y = str_split(y, "\\|")) %>% 
  unnest(y) %>% 
  mutate(value = 1) %>% 
  pivot_wider(names_from = y, values_from = value, values_fill = 0) %>% 
  as.data.frame() # 若需转换为普通data.frame而非tibble

方法2:基础R实现

手动初始化矩阵并填充值:

# 获取所有唯一的y类别
all_y <- unique(unlist(strsplit(foo$y, "\\|")))
# 创建结果数据框
foo_long2 <- data.frame(
  x = foo$x,
  matrix(0, nrow = nrow(foo), ncol = length(all_y))
)
colnames(foo_long2)[-1] <- all_y

# 为对应位置填充1
for(i in seq(nrow(foo))){
  y_vals <- strsplit(foo$y[i], "\\|")[[1]]
  foo_long2[i, y_vals] <- 1
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:29:55