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

如何在R中将列中逗号分隔值拆分到对应序号列

问卷多选数据按数值匹配列转换

原始数据

df <- data.frame(
  ID = 1:5,
  Var = c("3,12,14,15,16,18,20,21", "3,14,20", "3,14,16", "3,12", "3,6,14,15,17,20"),
  stringsAsFactors = FALSE
)

需求说明

需要将Var列中逗号分隔的数值,对应到以Var_XX命名的列中(XX为两位数字序号,从01到21):数值n就放入Var_0n列(n<10时补前导零),未匹配的列填充NA。

已尝试方法及问题

  • 使用str_split_fixed:按逗号拆分后,数值按出现顺序填充到列中,无法对应到序号匹配的列
library(stringr)
str_split_fixed(df$Var, ",", 21)

输出结果:

[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
[1,] "3"  "12" "14" "15" "16" "18" "20" "21" ""   ""    ""    ""    ""    ""   
[2,] "3"  "14" "20" ""   ""   ""   ""   ""   ""   ""    ""    ""    ""    ""   
[3,] "3"  "14" "16" ""   ""   ""   ""   ""   ""   ""    ""    ""    ""    ""   
[4,] "3"  "12" ""   ""   ""   ""   ""   ""   ""   ""    ""    ""    ""    ""   
[5,] "3"  "6"  "14" "15" "17" "20" ""   ""   ""   ""    ""    ""    ""    "" 
  • 使用cSplit:同样按拆分顺序生成列,不符合序号匹配需求
library(splitstackshape)
cSplit(df, "Var", ",")

输出结果:

ID Var_1 Var_2 Var_3 Var_4 Var_5 Var_6 Var_7 Var_8
1:  1     3    12    14    15    16    18    20    21
2:  2     3    14    20    NA    NA    NA    NA    NA
3:  3     3    14    16    NA    NA    NA    NA    NA
4:  4     3    12    NA    NA    NA    NA    NA    NA
5:  5     3     6    14    15    17    20    NA    NA

目标输出格式

ID Var_01 Var_02 Var_03 Var_04 Var_05 Var_06 Var_07 Var_08 ... Var_21
1:  1     NA     NA      3     NA     NA     NA     NA     NA ...      21
2:  2     NA     NA      3     NA     NA     NA     NA     NA ...     NA
3:  3     NA     NA      3     NA     NA     NA     NA     NA ...     NA
4:  4     NA     NA      3     NA     NA     NA     NA     NA ...     NA
5:  5     NA     NA      3     NA     NA      6     NA     NA ...     NA

解决方案

方法1:使用tidyverse工具链(推荐,适合学习)

利用tidyr的separate_rows将长字符串拆分成行,再用pivot_wider将行转换为对应序号的列,最后补全所有需要的列并排序。

library(tidyverse)

# 1. 拆分Var列为多行,生成规范列名
df_long <- df %>%
  separate_rows(Var, sep = ",") %>%
  mutate(
    Var = as.integer(Var),
    col_name = str_glue("Var_{str_pad(Var, 2, pad = '0')}")
  )

# 2. 转换为宽格式,填充NA
df_wide <- df_long %>%
  pivot_wider(
    id_cols = ID,
    names_from = col_name,
    values_from = Var,
    values_fill = NA_integer_
  )

# 3. 补全Var_01到Var_21的所有列,确保无遗漏
all_cols <- str_glue("Var_{str_pad(1:21, 2, pad = '0')}")
df_final <- df_wide %>%
  select(ID, all_of(all_cols))

# 查看结果
print(df_final)

方法2:基础R实现

通过创建空矩阵,循环填充对应位置的值,适合理解底层逻辑。

# 初始化结果矩阵:行数为df的行数,列数21,填充NA
result_matrix <- matrix(NA_integer_, nrow = nrow(df), ncol = 21)
colnames(result_matrix) <- sprintf("Var_%02d", 1:21)

# 循环每一行,填充对应位置
for(i in 1:nrow(df)){
  # 拆分当前行的Var值为整数向量
  vals <- as.integer(strsplit(df$Var[i], ",")[[1]])
  # 数值n对应第n列,填充值
  result_matrix[i, vals] <- vals
}

# 转换为数据框,合并ID列
df_final <- cbind(df$ID, as.data.frame(result_matrix))
colnames(df_final)[1] <- "ID"

# 查看结果
print(df_final)

说明

  • tidyverse方法简洁易读,适合日常数据处理;基础R方法能帮助理解数据结构转换逻辑,适合学习阶段深入掌握。
  • 拆分后需将数值转换为整数类型,避免字符串类型导致的索引错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:22:47