在data.frame中保留单个主组,将重复主组的子组移至其下方
无循环实现R数据的分组扁平化转换
我知道这个问题表述可能不够精准,要是能优化措辞说不定早就在其他帖子里找到答案了。现有如下数据结构:
df <- data.frame(group = c("X", "F", "F", "F", "F", "C", "C"), subgroup = c(NA, "camel", "horse", "dog", "cat", "orange", "banana"))
希望将其转换为:
data.frame(group = c("X", "F", "camel", "horse", "dog", "cat", "C", "orange", "banana"))
这个转换操作比预想的棘手,要求不使用循环,且更新示例后,依赖排序的方案无法满足需求。
解决方案1:使用tidyverse工具链
利用dplyr的分组汇总功能,结合向量拼接实现,全程无循环且保留原始顺序:
library(dplyr) df <- data.frame(group = c("X", "F", "F", "F", "F", "C", "C"), subgroup = c(NA, "camel", "horse", "dog", "cat", "orange", "banana")) result <- df %>% group_by(group) %>% summarise( # 每组先保留group本身,再追加非NA的subgroup值 new_group = c(first(group), na.omit(subgroup)), .groups = "drop" # 取消分组状态 ) %>% pull(new_group) %>% # 提取向量 data.frame(group = .) # 转换为数据框 # 输出结果 print(result)
解决方案2:Base R实现
无需额外包,用lapply处理每个唯一分组,同样无循环且保留原始顺序:
df <- data.frame(group = c("X", "F", "F", "F", "F", "C", "C"), subgroup = c(NA, "camel", "horse", "dog", "cat", "orange", "banana")) # 获取原始顺序的唯一分组值 unique_groups <- unique(df$group) # 对每个分组生成目标向量 output_list <- lapply(unique_groups, function(g) { subgroup_vals <- na.omit(df$subgroup[df$group == g]) c(g, subgroup_vals) }) # 合并向量并转为数据框 result <- data.frame(group = unlist(output_list)) # 输出结果 print(result)
两种方案都会严格保留原始group的出现顺序,以及每个group下subgroup的原有顺序,不会依赖排序操作。
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

