R语言数据框单行多列不等长值拆多行及separate_rows报错解决
问题说明
现有563列的数据框,初始仅1行,每列存储长度不等的多值向量,示例结构:
col_1 col_2 col_3 ... col_563 c("1","2","3") c("1","2","3"...) c("1","2") c("1","2","3"...)
需要将各列的多值拆分到独立行,短序列对应位置留空,目标效果:
col_1 col_2 col_3 ... col_563 "1" "1" "1" "1" "2" "2" "2" "2" "3" "3" "3" "4" "4" "5"
之前使用如下代码尝试实现:
separate_rows(df, "row1":"row563", convert = TRUE)
运行触发报错:
Error in `fn()`: ! In row 1, can't recycle input of size 778 to size 124.
报错原因
separate_rows() 执行拆分时,要求同一行内所有待拆分列拆分后的元素长度符合R向量回收规则,也就是要么长度完全相等,要么短向量长度是长向量的整倍数。你的数据里各列序列长度从124到778不等,不满足回收要求,因此报错。
实现方法
方法1:base R 无依赖实现
逻辑简单直接,不需要加载第三方包,运行效率高:
# 第一步:把每列的向量提取为列表元素 split_cols <- lapply(df, unlist) # 第二步:计算所有列的最大长度,作为最终结果的总行数 total_row <- max(vapply(split_cols, length, integer(1))) # 第三步:逐列补齐长度,短列缺失位置自动补NA,再合并为数据框 result <- as.data.frame( lapply(split_cols, function(col_val) { length(col_val) <- total_row col_val }) ) # 如果需要把缺失值替换为空字符串,执行下面这行即可 result[is.na(result)] <- ""
方法2:tidyverse 生态实现
如果平时习惯用dplyr、tidyr的语法,可以用下面的代码:
library(tidyverse) result <- df %>% # 先把所有列的向量展开为列表列 mutate(across(everything(), unlist)) %>% # 按最长序列长度生成行索引 mutate(idx = list(seq_len(max(lengths(cur_data()))))) %>% # 按索引展开行,逐列取对应位置的值 unnest_longer(idx) %>% mutate(across(-idx, ~ .x[idx])) %>% select(-idx) %>% # 需要空字符串替换NA就打开下面注释 # mutate(across(everything(), replace_na, ""))
补充:如果你的原始单元格存的是逗号/其他符号分隔的字符串,不是R原生向量,只需要在提取向量的步骤加分割逻辑即可,比如把
unlist(x)替换为unlist(strsplit(x, ",")),分隔符按实际情况调整。
内容的提问来源于stack exchange,提问作者Linda
相关产品推荐
相关产品推荐

