如何以非规整方式合并DataFrame并聚合成员列?优化代码及处理缺失值
嘿,我来帮你搞定这个DataFrame合并的问题!你的核心需求是按Artist聚合成员并合并到主表,其实有更简洁、通用的实现方式,下面逐个解决你的疑问:
1. 更简便的实现方式
你原来的方法用到了spread+unite,步骤有点绕,其实用dplyr的分组聚合就能一步搞定,不需要拆分再合并:
library(tidyverse) # 你的原始数据 df1 <- data.frame(stringsAsFactors=FALSE, Artist = c("Beatles", "Rolling Stones"), Album = c("Sgt. Pepper's", "Sticky Fingers"), Year = c(1967, 1971) ) df2 <- data.frame(stringsAsFactors=FALSE, Artist = c("Beatles", "Beatles", "Beatles", "Beatles"), Members = c("George", "Ringo", "Paul", "John") ) # 核心步骤:先聚合df2的成员,再和df1合并 df_merged <- df2 %>% group_by(Artist) %>% summarize(Members = str_c(Members, collapse = ", ")) %>% # 把成员用逗号分隔合并成字符串 left_join(df1, ., by = "Artist") %>% # 左连接到主表,保留所有乐队信息 select(Artist, Album, Members, Year) # 调整列顺序和你的期望输出一致
运行后得到的结果已经非常接近你的需求:
#> Artist Album Members Year
#> 1 Beatles Sgt. Pepper's George, Ringo, Paul, John 1967
#> 2 Rolling Stones Sticky Fingers1971
2. 通用化适配任意成员数量
上面的方法天生就是通用的!不管某个乐队有1个、11个还是13个成员,group_by(Artist) %>% summarize(str_c(Members, collapse = ", "))都会自动把该乐队下所有成员合并成一个字符串,不需要手动指定成员数量或者列名,完美适配各种规模的乐队数据。
3. 将缺失值改为空值
要把Rolling Stones对应的NA改成空值,只需要在合并后加上replace_na处理即可:
df_merged_final <- df_merged %>% mutate(Members = replace_na(Members, ""))
最终输出完全符合你的期望:
#> Artist Album Members Year
#> 1 Beatles Sgt. Pepper's George, Ringo, Paul, John 1967
#> 2 Rolling Stones Sticky Fingers 1971
内容的提问来源于stack exchange,提问作者Jeremy K.

