将含重复观测的长格式数据转换为带汇总列的短格式数据
解决长格式转逗号分隔短格式的问题
没问题,我来帮你搞定这个数据格式转换的需求!你之前的代码绕了弯路,其实用dplyr的summarise结合字符串拼接函数就能一步到位,而且更通用(不管每个obs对应多少个code都能处理)。
问题分析
你原来的方法用了spread+unite,但这个思路有两个明显问题:
- 如果某个
obs对应的code数量超过2个,你的代码就会漏掉后续的code(因为你只合并了第2、3列) - 步骤繁琐,没必要先转成多列再合并,完全可以一步完成分组拼接
正确解决方案
直接在分组后,用summarise把每个组的code值用逗号拼接起来即可,推荐用stringr::str_c(或者基础R的paste也能实现):
library(dplyr) # 如果用str_c的话需要加载stringr包 library(stringr) # 创建你的示例数据集 df <- data.frame( obs=c("1","2","4","2","1","3"), code=c("A","B","G","D","H","K"), stringsAsFactors = F ) # 核心转换代码 df_short <- df %>% group_by(obs) %>% summarise(code = str_c(code, collapse = ", ")) %>% # 用逗号分隔拼接同组的code ungroup() # 记得取消分组,避免后续操作受分组状态影响 # 查看最终结果 df_short
运行后得到的结果完全符合你的预期:
# A tibble: 4 × 2 obs code <chr> <chr> 1 1 A, H 2 2 B, D 3 3 K 4 4 G
如果你不想额外加载stringr包,用基础R的paste函数也能实现同样效果,把summarise那行改成:
summarise(code = paste(code, collapse = ", "))
为什么原来的代码没达到预期?
你原来的代码先给每个组加了序号id,再转成宽格式,最后合并列,但这种方式只适用于每个obs最多对应2个code的场景,如果有更多code就会遗漏,而且生成的中间列完全是冗余的。用summarise+字符串拼接的方法更简洁、更通用,能适配任意数量的分组内元素。
内容的提问来源于stack exchange,提问作者captcoma
相关产品推荐
相关产品推荐

