【问题标题】:Merging datasets by name when names have different formats in R当名称在R中具有不同格式时按名称合并数据集
【发布时间】:2014-05-27 01:59:40
【问题描述】:

我在 R 中有两个不同的数据框,我正在尝试将它们合并在一起。一个只是一组名称,另一个是一组名称,其中包含每个人的相应信息。

所以说我想获取第一个数据帧:

Name
1. Blow, Joe
2. Smith, John
3. Jones, Tom 
etc....

并将其合并到这个:

   DonorName  CandidateName DonationAmount CandidateParty
1   blow joe Bush, George W          3,000     Republican
2   guy some  Obama, Barack          5,000       Democrat
3 smith john    Reid, Harry          4,000       Democrat

这样我就有一个新列表,其中仅包含我的第一个列表中的人员以及第二个列表中的信息。如果两个“名称”值的格式相同,我可以只使用merge(),但是有没有办法以某种方式使用agrep() 或pmatch() 来做到这一点?

另外,我正在使用的第二个数据帧中有大约 2500 万行和 6 列,那么制作 for 循环是最快的方法吗?

示例数据的可重现版本:

first <- data.frame(Name=c("Blow, Joe","Smith, John","Jones, Tom"),
         stringsAsFactors=FALSE)

second <- read.csv(text="
DonorName|CandidateName|DonationAmount|CandidateParty
blow joe|Bush, George W|3,000|Republican
guy some|Obama, Barack|5,000|Democrat
smith john|Reid, Harry|4,000|Democrat",header=TRUE,sep="|",
stringsAsFactors=FALSE)

【问题讨论】:

  • 您的格式在每个数据集中是否始终相同,还是在每个数据集中有所不同?
  • @StanO 这个问题已经回答了哪个有效的解决方案?如果不是,请提出需要的建议,否则请接受适当的解决方案,或者如果下面没有提供,请写下+接受您自己的解决方案
  • 对不起,我以为我已经检查了您的答案,但似乎没有。迟来的感谢您对此提出的宝贵建议!

标签: r merge fuzzy-search agrep


【解决方案1】:

解决方案:

first$DonorName <- gsub(", "," ",tolower(first$Name),fixed=TRUE)

require(dplyr)

result <- inner_join(first,second,by="DonorName")

如果数据与您提供的一样,将为您提供所需的数据。

result
         Name  DonorName  CandidateName DonationAmount CandidateParty
1   Blow, Joe   blow joe Bush, George W          3,000     Republican
2 Smith, John smith john    Reid, Harry          4,000       Democrat

“解决这个问题的快速方法”

如上dplyr方法:

f_dplyr <- function(left,right){
   left$DonorName <- gsub(", "," ",tolower(left$Name),fixed=TRUE)
   inner_join(left,right,by="DonorName")
}

data.table方法,先设置key。

f_dt <- function(left,right){
   left[,DonorName :=  gsub(", "," ",tolower(Name),fixed=TRUE)]
   setkey(left,DonorName)
   left[right,nomatch=0L]
}

data.table 方法,设置两个键。

f_dt2 <- function(left,right){
   left[,DonorName :=  gsub(", "," ",tolower(Name),fixed=TRUE)]
   setkey(left,DonorName)
   setkey(right,DonorName)
   left[right,nomatch=0L]
}

base方法依赖sapply:

f_base <- function(){
  second[second$DonorName %in%
  sapply(tolower(first[[1]]), gsub, pattern = ",", replacement = "", fixed = TRUE), ]
}

让我们在 1M obs 下让第二个 df 更真实一点,以便进行公平的比较:

second <- cbind(second[rep(1:3,1000000),],data.frame(varn= 1:1000000))
left <- as.data.table(first)
right <- as.data.table(second)

library(microbenchmark)

microbenchmark(
          f_base(),
          f_dplyr(first,second),
          f_dt(left,right),
          f_dt2(left,right),
          times=20)

我们得到:

Unit: milliseconds
                   expr       min        lq    median        uq       max neval
               f_base() 2880.6152 3031.0345 3097.3776 3185.7903 3904.4649    20
 f_dplyr(first, second)  292.8271  362.7379  454.6864  533.9147  774.1897    20
      f_dt(left, right)  489.6288  531.4152  605.4148  788.9724 1340.0016    20
     f_dt2(left, right)  472.3126  515.4398  552.8019  659.7249  901.8133    20

在我的机器上,通过这个 ?contrived 示例,我们比 base 方法获得了大约 2.5 秒。根据我的经验,sapply 进行了简化并且无法很好地扩展...当您增加 firstsecond 中唯一组的数量时,这种差距可能会变得更大。

如果您想出更有效的使用方法,请随时编辑。我不假装知道,但我总是尝试学习一些东西。

【讨论】:

  • 很好,但这仅涵盖基准测试的一个方面 - 即大量行。它共有 5 个独特的组。 Here's a gist 说明了我从各种基准测试中了解到的其他两个因素 - 唯一组的数量和执行连接的列数。
  • @Arun 我怀疑可能会根据数据结构进行交易。现在我认为这些理念?从根本上不同,但我肯定会发现在两个存储库主页上提供一些友好竞争 + 大量公开公平比较作为文档的想法。我敢说托管Shiny 应用会浪费时间吗?
  • 对。这非常耗时,尤其是涵盖所有情况。不过,我已经尝试了很多案例。希望我们能尽快将它们发布在我们的主页上。
  • @Arun。好吧,您知道我们的最终用户,内置了寄生行为。话虽如此,也许只是启动一个仅充当“结果转储”的共享存储库会很有趣。因此,任何人都可以在他们自己的机器上提交特定比较的要点/拉取请求(例如以缓存的 .rmd 的形式),然后维护人员可以在合并之前进行验证。然后您还可以看到比较的可重复性(实验)不仅是一个用户,而且是一个用户社区。只是 FFT(深思)。
  • 一个大问题是,我不认为基准测试“ms”或“us”有用(在为大数据开发的工具上)。我想压力测试,看看每个人在哪里休息。我一直在对 1/2 - 10 亿行不同组大小的行进行基准测试。我(和其他人可以)非常清楚地看到每个工具的缩放或损坏程度。
【解决方案2】:

没有dplyr

second[second$DonorName %in%
  sapply(tolower(first[[1]]), gsub, pattern = ",", replacement = "", fixed = TRUE), ]

结果:

#     DonorName  CandidateName DonationAmount CandidateParty
# 1   blow joe  Bush, George W          3,000     Republican
# 3 smith john     Reid, Harry          4,000       Democrat

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-04
    • 2023-02-24
    • 1970-01-01
    • 2015-11-09
    • 2022-01-02
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多