在R中处理大型数据集
我有一个约5百万行的企业数据集,其中包含联系信息(ID(int)、电子邮件(text)、商务电话(text)、工作电话(text)、手机(text))——其中超过300万行包含重复数据。但这些复制品并不是完全的复制品——例如,可能有多行电话号码中有不同的电子邮件地址 我想让每一行都有唯一的信息,这样我的数据文件中就不会有重复的电话号码或电子邮件。我计划通过一个新列将列聚合到列表中来实现这一点。此列(我们称之为ROWIDs)应该是包含该行中出现的一个或多个联系人数据点(电子邮件、商务电话、工作电话、手机)的所有ID的串联 我已经编写了适用于小样本的代码,但我不知道如何扩展它 注意:缺少电话号码的行(3列中的任意一列)有一个“NA”文本占位符。 行示例:在R中处理大型数据集,r,dplyr,data.table,doparallel,parallel-foreach,R,Dplyr,Data.table,Doparallel,Parallel Foreach,我有一个约5百万行的企业数据集,其中包含联系信息(ID(int)、电子邮件(text)、商务电话(text)、工作电话(text)、手机(text))——其中超过300万行包含重复数据。但这些复制品并不是完全的复制品——例如,可能有多行电话号码中有不同的电子邮件地址 我想让每一行都有唯一的信息,这样我的数据文件中就不会有重复的电话号码或电子邮件。我计划通过一个新列将列聚合到列表中来实现这一点。此列(我们称之为ROWIDs)应该是包含该行中出现的一个或多个联系人数据点(电子邮件、商务电话、工作电话
before:
ID Email BusinessPhone WorkPhone CellPhone
1 test@mail.com 5555555555 NA 9998887777
2 NA 5555555555 873998898 NA
Desired After:
ID Email BusinessPhone WorkPhone CellPhone ROWIDs
1 test@mail.com 5555555555 NA 9998887777 1,2
2 NA 5555555555 873998898 NA 1,2
对于1000行的随机样本,system.time如下所示:
用户:0.75
系统:0.12
时间:1.35
这在5000行时呈指数增长:
用户:12.55
系统:1.50
时间:16.72
和10000:
用户:50.97
系统:16.77
时间:71.88
这离我的起点还有很长的一段路要走,但这是我目前所能做到的。非常感谢您的帮助或指导。不确定这对于您的数据集是否足够快,您可以使用
igraph
来识别指向同一个人的id簇:
library(igraph)
edges <- melt(DT[, (names(DT)) := lapply(.SD, as.character)], id.vars="ID", na.rm=TRUE)[,
if (.N > 1L) transpose(combn(ID, 2L, simplify=FALSE)), value][, (1) := NULL]
g <- graph_from_data_frame(edges, FALSE)
mem <- setDT(stack(clusters(g)$membership))[, ROWIDs := toString(ind), values]
DT[mem, on=.(ID=ind), ROWIDs := ROWIDs]
DT
库(igraph)
边1L)转置(combn(ID,2L,simplify=FALSE)),值][,(1):=NULL]
你不应该把数据分成多个表吗?一个具有不变数据(例如ID、生日)、一个用于邮件(ID、mail)、一个用于商务电话(ID、电话号码)等,作为一个关系数据集,用于识别具有ID的个人并从其他表获取信息,即使我这样做了,我仍然需要合并重复的行,并为每一行分配一个rowID。这样做的想法是为每个人找到一个唯一的标识符,并使用它将所有表链接在一起。这样,每个表都包含唯一的值,但不会丢失任何内容并限制重复,因为两个不同的邮件并不意味着重复所有其他字段。最后,您将如何处理这些数据?这将告诉你需要如何格式化them@Gallarus,我很感谢您提供的关于数据库最佳实践的信息,但我有一个凌乱的文件需要在做出决定之前进行重复数据消除。好的,我想我误解了您的问题。你能提供你想要的输入数据和结果的示例吗?大概有10行凌乱的数据和你最后应该拥有的东西。
library(igraph)
edges <- melt(DT[, (names(DT)) := lapply(.SD, as.character)], id.vars="ID", na.rm=TRUE)[,
if (.N > 1L) transpose(combn(ID, 2L, simplify=FALSE)), value][, (1) := NULL]
g <- graph_from_data_frame(edges, FALSE)
mem <- setDT(stack(clusters(g)$membership))[, ROWIDs := toString(ind), values]
DT[mem, on=.(ID=ind), ROWIDs := ROWIDs]
DT
ID Email BusinessPhone WorkPhone CellPhone ROWIDs
1: 1 test@mail.com 5 <NA> 7 1, 2
2: 2 <NA> 5 6 <NA> 1, 2
3: 3 aaaa@mail.com <NA> <NA> <NA> 3, 4
4: 4 aaaa@mail.com <NA> 1 <NA> 3, 4
5: 5 bbbb@mail.com <NA> 3 <NA> 5, 6
6: 6 <NA> <NA> 3 <NA> 5, 6
7: 7 cccc@mail.com <NA> <NA> 4 7, 8
8: 8 <NA> <NA> <NA> 4 7, 8
library(data.table)
DT <- fread("
ID Email BusinessPhone WorkPhone CellPhone
1 test@mail.com 5 NA 7
2 NA 5 6 NA
3 aaaa@mail.com NA NA NA
4 aaaa@mail.com NA 1 NA
5 bbbb@mail.com NA 3 NA
6 NA NA 3 NA
7 cccc@mail.com NA NA 4
8 NA NA NA 4
")