如何在嵌套数据框中提取唯一行集合并移除重复活动家庭?
嘿,我来帮你搞定这个批量去重的问题,而且这个方案专门适配你6万+家庭的大数据场景,效率拉满:
核心思路
要解决这个问题,我们需要分三步走:先清理每个家庭内部的重复行并重新编号,再给每个家庭的活动集合生成唯一标识(避免两两比较的低效),最后批量移除重复的家庭活动集合。
步骤1:预处理家庭数据,清理内部重复并重新编号
首先,我们先对每个家庭内的活动行去重,同时给家庭(shid)和成员(smid)分配顺序编号——原ID的实际意义我们不需要保留:
library(dplyr) library(tidyr) library(purrr) library(jsonlite) # 第一步:清理家庭内重复行,并重编家庭/成员ID df_preprocessed <- df %>% # 按家庭分组,移除组内重复的活动行(只保留唯一的活动组合) group_by(hid) %>% distinct(tmid, thid, tdid, tiid, .keep_all = FALSE) %>% # 给当前家庭的成员分配顺序编号smid mutate(smid = row_number()) %>% ungroup() %>% # 给所有家庭分配顺序编号shid mutate(shid = dense_rank(hid))
步骤2:生成家庭活动集合的唯一标识,批量去重
大数据场景下,两两比较嵌套数据框效率极低,我们可以把每个家庭的活动集合转换成标准化的JSON字符串——相同结构的活动集合会生成完全一致的字符串,这样就能快速判断重复:
# 第二步:嵌套数据框,生成活动集合的唯一哈希标识 df_nested <- df_preprocessed %>% group_by(shid) %>% # 把每个家庭的成员活动数据嵌套成子数据框 nest(data = c(smid, tmid, thid, tdid, tiid)) %>% # 将子数据框转为JSON字符串,作为该家庭活动集合的唯一标识 mutate(activity_signature = map_chr(data, ~ toJSON(.x, auto_unbox = TRUE))) %>% # 移除重复的活动集合(只保留第一个出现的家庭) distinct(activity_signature, .keep_all = TRUE) %>% # 清理掉临时的标识列 select(-activity_signature)
如果你的数据集特别大,担心JSON字符串占用内存,可以用digest包把JSON转成更紧凑的MD5哈希值:
library(digest) df_nested <- df_preprocessed %>% group_by(shid) %>% nest(data = c(smid, tmid, thid, tdid, tiid)) %>% mutate(activity_signature = map_chr(data, ~ digest(toJSON(.x, auto_unbox = TRUE), algo = "md5"))) %>% distinct(activity_signature, .keep_all = TRUE) %>% select(-activity_signature)
步骤3:展开嵌套数据框,得到最终结果
最后把嵌套的子数据框展开,就是我们需要的唯一家庭活动集合:
# 第三步:展开嵌套数据,得到最终结果 df_final <- df_nested %>% unnest(data) %>% arrange(shid, smid) # 查看结果 print(df_final)
运行后你会得到和期望一致的输出:
- 每个家庭内部的重复行已经被移除
- 活动集合完全重复的家庭(比如原
hid=3)被自动移除 shid和smid都是顺序编号,没有原ID的冗余信息
内容的提问来源于stack exchange,提问作者HSJ
相关产品推荐
相关产品推荐

