【问题标题】:Merging data frames with predictable typos将数据框与可预测的错别字合并
【发布时间】:2013-04-23 16:48:18
【问题描述】:

我需要合并两个数据框。第一个看起来像这样:

> df1 <- data.frame(Artist = c("Vincent van ", "Vincent van ", "Theo van Gogh", "Alexandre", "Alexandre"), Location = c("a","a","a","b","c"), time = c(1,2,1,1,1))
> df1
         Artist Location time
1  Vincent van         a    1
2  Vincent van         a    2
3 Theo van Gogh        a    1
4     Alexandre        b    1
5     Alexandre        c    1

第二个:

> df2 <- data.frame(Artist = c("Vincent van Gogh", "Theo van Gogh", "Alexandre Dumas", "Alexandre Dumas"), HomeNumber = c(123,234,456,789), Location = c( "a","a","b","c"))
> df2
            Artist HomeNumber Location
1 Vincent van Gogh        123        a
2    Theo van Gogh        234        a
3  Alexandre Dumas        456        b
4  Alexandre Dumas        789        c

我想要这个数据框:

> df3 <- data.frame(Artist = c("Vincent van ", "Vincent van ", "Theo van Gogh", "Alexandre", "Alexandre"), Location = c("a","a","a","b","c"), time = c(1,2,1,1,1), HomeNumber = c(123,123,234,456,789))
> df3
         Artist Location time HomeNumber
1  Vincent van         a    1        123
2  Vincent van         a    2        123
3 Theo van Gogh        a    1        234
4     Alexandre        b    1        456
5     Alexandre        c    1        789
> 

合并仅适用于 Theo:

    > df3 <- merge(df1, df2, by.x = "Artist", by.y = "Artist", all.x =TRUE)
> df3
         Artist Location.x time HomeNumber Location.y
1     Alexandre          b    1         NA       <NA>
2     Alexandre          c    1         NA       <NA>
3 Theo van Gogh          a    1        234          a
4  Vincent van           a    1         NA       <NA>
5  Vincent van           a    2         NA       <NA> 

原因有两个: (a) 文森特在df1 中缺少部分姓氏。 (b) 亚历山大是大仲马和大仲马的名字。

我可以用df1$Artist &lt;- gsub("Vincent van $","Vincent van Gogh", df1$Artist)处理(a),但我的数据实际上非常大,在执行gsub之前我必须先知道文森特的全名。一种可能的解决方案是在 df2 中使用grep("Vincent van "...,构建一个函数,如果结果向量的长度为1,我将使用gsub 来使用返回的df2$Artistdf1。我不知道该怎么做。

(b) 对我来说有点棘手。我能想到的一个解决方案(但不能编码)是首先使用if函数从一个位置选择Alexandre,然后使用(a)的解决方案gsub名称。

我认为解决 (a) 和 (b) 将返回我想要的 df3。你们知道如何有效地合并这些数据框吗?谢谢!

编辑:请注意,Alexandre 实际上是两个不同的单位。因此,当合并两者时,应该有它们关联的 HomeNumber 和 Location。 Vincent 是一个单一的单元,但有两个时间观察。

【问题讨论】:

  • 您可以尝试使用match() 函数,您可以将location 作为匹配参数,其余列显示在新的data.frame 中
  • 函数agrep 进行模糊字符串匹配。您还可以采取一些修改步骤,例如tolower 并删除标点符号以提供帮助...但最简单的答案是数据修改很乏味!
  • @Duck:它可能会有所帮助,但我看不出它会如何解决问题。谢谢! @贾斯汀:我知道!极其乏味。我已经使用了tolowerchartr 和其他一些功能。

标签: r dataframe merge gsub


【解决方案1】:

您希望该结果受到破坏,因为您必须在每个数据帧中有两行您想要考虑具有相同的 id,即Alexandre 行。 JOIN 过程将使其成为 2 x 2 匹配:

df2$short <- substr(df2$Artist, 1,7)
df1$short <- substr(df1$Artist, 1,7)
(dfmer <- merge(df1, df2, by="short") )
#-----
    short      Artist.x Location.x time         Artist.y HomeNumber Location.y
1 Alexand     Alexandre          b    1  Alexandre Dumas        456          b
2 Alexand     Alexandre          b    1  Alexandre Dumas        789          c
3 Alexand     Alexandre          c    1  Alexandre Dumas        456          b
4 Alexand     Alexandre          c    1  Alexandre Dumas        789          c
5 Theo va Theo van Gogh          a    1    Theo van Gogh        234          a
6 Vincent  Vincent van           a    1 Vincent van Gogh        123          a
7 Vincent  Vincent van           a    2 Vincent van Gogh        123          a

如果您想挑选第一个实例,您可以使用 !duplicated on location 和 time:

> dfmer[!duplicated( dfmer[, c("Location.x", "time")]), ]
    short      Artist.x Location.x time         Artist.y HomeNumber Location.y
1 Alexand     Alexandre          b    1  Alexandre Dumas        456          b
3 Alexand     Alexandre          c    1  Alexandre Dumas        456          b
5 Theo va Theo van Gogh          a    1    Theo van Gogh        234          a
7 Vincent  Vincent van           a    2 Vincent van Gogh        123          a

回应关注(之前没有提出需要添加Location作为链接变量:

> (dfmer <- merge(df1, df2, by=c("short", "Location") ) )
    short Location      Artist.x time         Artist.y HomeNumber
1 Alexand        b     Alexandre    1  Alexandre Dumas        456
2 Alexand        c     Alexandre    1  Alexandre Dumas        789
3 Theo va        a Theo van Gogh    1    Theo van Gogh        234
4 Vincent        a  Vincent van     1 Vincent van Gogh        123
5 Vincent        a  Vincent van     2 Vincent van Gogh        123

【讨论】:

  • 谢谢,@Dwin。但是,请注意 Alexandre from Location 'c' 的 HomeNumber 错误
  • 如果 HomeNumber 与共享标识符相关联,我相信它与 Location 相关联,那么您应该将该标识符添加到 by 变量中。
猜你喜欢
  • 2019-11-06
  • 2019-03-25
  • 1970-01-01
  • 2018-02-10
  • 2015-11-19
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
相关资源
最近更新 更多