如何在R中将data.frame含分号的列拆分并生成新行?
拆分data.frame中带分号的列并复制对应行
原始数据
df <- data.frame(id = c(1:12), A = c("alpha", "alpha", "beta", "beta", "gamma", "gamma", "gamma", "delta", "epsilon", "epsilon", "zeta", "eta"), B = c("a", "a; b", "a", "c; d; e", "e", "e", "c; f", "g", "a", "g; h", "f", "d"), C = c(NA, 4, 2, 7, 4, NA, 9, 1, 1, NA, 3, NA), D = c("ii", "ii", "i", "iii", "iv", "v", "viii", "v", "viii", "i", "iii", "i"))
需求说明
拆分B列中以; 分隔的条目,复制对应行并将每个单独值填入新行的B列,得到目标数据框df2。
你的代码问题分析
你尝试的代码存在几个关键错误:
- 修改
df2$B为拆分后的向量后,df2的行数已与原数据不一致,后续用原行号重复会导致数据错位; - 代码中出现未定义的
df1,应为原数据框df; - 重复
id的逻辑错误,会导致id被多次重复,而非对应原行的id复制。
解决方案
方案1:使用tidyr包(简洁高效)
tidyr::separate_rows()可以直接完成拆分列并复制对应行的操作,无需手动处理行重复:
library(tidyr) df2 <- df %>% separate_rows(B, sep = "; ")
方案2:Base R实现
如果不想加载额外包,可通过以下步骤实现:
# 拆分B列得到每个元素的列表 split_B <- strsplit(as.character(df$B), "; ") # 计算每个拆分后元素的长度,用于行重复 row_counts <- sapply(split_B, length) # 重复原数据的行,匹配拆分后的元素数量 df2 <- df[rep(seq_len(nrow(df)), row_counts), ] # 将拆分后的B列值替换到新数据框中 df2$B <- unlist(split_B) # 按id排序(与预期结果一致) df2 <- df2[order(df2$id), ]
两种方案运行后得到的结果均与你预期的df2完全一致。
内容的提问来源于stack exchange,提问作者Sylvia Rodriguez
相关产品推荐
相关产品推荐

