在 R 中处理大型数据集

Posted

技术标签:

【中文标题】在 R 中处理大型数据集【英文标题】:Processing Large Data Sets in R 【发布时间】:2020-05-21 21:09:28 【问题描述】:

我有一个约 5 毫米行的企业数据集,其中包含联系信息(ID(int)、Email(text)、BusinessPhone(text)、WorkPhone(text)、CellPhone(text))——其中超过 300 万行包含重复数据。但这些骗子并不完全是骗子 - 例如,可能有多个行中的电话号码具有不同的电子邮件地址。

我想让每一行都有唯一的信息,这样我的数据文件中就没有重复的电话号码或电子邮件。我计划通过新列将列聚合到列表中来做到这一点。此列(我们称为 ROWID)应该是包含该行中出现的 1 个或多个联系人数据点(Email、BusinessPhone、WorkPhone、CellPhone)的所有 ID 的串联。

我编写了适用于小样本量的代码,但我不知道如何对其进行缩放。

注意:缺少电话号码的行(3 列中的任何一个)有一个“NA”文本占位符。 行示例:

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
library(foreach)
library(doParallel)

registerDoParallel(cores = detectCores())
getDoParWorkers() # (4)

#################### GET MATCHING ROW IDs ######################################################
d = ID(int), Email(char), BusinessPhone(char), WorkPhone(char), CellPhone(char), ROWIDs(all values are '0', col is character vector)

row = function(d) 

foreach(i = 1:nrow(d),.packages = c('dplyr','data.table','tidyverse')) %dopar% 

# 1. IDENTIFY LIST OF ROW IDS THAT CONTAIN CONTACT DATA FROM THE GIVEN ROW:
rowIDList = d[(emailp == emailp[i] & emailp != '') | 
              (BusinessPhone %in% c(BusinessPhone[i],WorkPhone[i],CellPhone[i]) & BusinessPhone != 0) | 
              (WorkPhone %in% c(BusinessPhone[i],WorkPhone[i],CellPhone[i]) & WorkPhone != 0) |
              (CellPhone %in% c(BusinessPhone[i],WorkPhone[i],CellPhone[i]) & CellPhone != 0),
            paste(ID, sep = ',')] %>% as.integer()

# 2. GET THE ROW IDS INTO CHARACTER FORM TO LIST THEM IN THE NEW COLUMN:
rowIDs = paste(rowIDList, collapse = ',') %>% as.character()

# 3. EDIT THE NEW COLUMN FOR THE SUBSET OF ROWS THAT CONTAIN DATA FROM THE ROW IN THE LOOP ITERATION: 
d[ID %in% rowIDList,
  try := rep(rowIDs,
             length(rowIDList))]





对于 1000 行的随机样本,system.time 如下: 用户:0.75 系统:0.12 经过:1.35

这在 5,000 行时呈指数增长: 用户:12.55 系统:1.50 经过:16.72

还有 10,000: 用户:50.97 系统:16.77 经过:71.88

这距离我开始的地方还有很长的路要走,但这是我目前的技能所能承受的。感谢您提供任何帮助或指导。

【问题讨论】:

您不应该将数据分成多个表吗?一个包含不变数据(例如 ID、出生日期)、一个用于邮件(ID、邮件)、一个用于业务电话(ID、电话号码)等。作为一个关系数据集,用于识别具有 ID 的个人并从中获取信息其他表 即使我这样做了,我仍然需要合并重复的行并为每一行分配一个 rowID。 我们的想法是为每个人找到一个唯一标识符,并使用它将所有表格链接在一起。这样,每个表都包含唯一值,但您不会丢失任何内容并限制重复,因为两个不同的邮件并不意味着重复所有其他字段。最后你将如何处理这些数据?这将告知您需要如何格式化它们 @Gallarus,我很欣赏关于数据库最佳实践的输入,但我有一个凌乱的文件,我需要在做出决定之前对其进行重复数据删除。 好的,我想我误解了你的问题。你能提供你想要的输入数据和结果的例子吗?像 10 行杂乱无章的数据,以及你最终应该拥有的东西。 【参考方案1】:

不确定这对于您的数据集是否足够快,您可以使用 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

输出:

   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
")

【讨论】:

以上是关于在 R 中处理大型数据集的主要内容,如果未能解决你的问题,请参考以下文章

R中用于大型复杂调查数据集的方法?

R:循环处理大数据集(GB)的块?

如何在 R/Python 中迭代/循环一个大型(>2GB)JSON 数据集? [复制]

R读取大型数据集内存不足如何解决,如果利用Linux有啥有效方法吗?

R:具有 2 个大型数据集的模式匹配金融时间序列数据:

大型数据集上的 R 中的矩阵数学