【问题标题】:Merge data sets based on two column values基于两列值合并数据集
【发布时间】:2014-03-11 20:46:20
【问题描述】:

我到处寻找,但似乎无法找到解决我遇到的这个小问题的可行解决方案。

我有两个大型数据集,N=875 和 N=922。

df.1 包含 875 个 obs 和 27 个 var 的数据集 df.2 具有 922 obs 23 var 的数据集

df.1 有列 FIRSTLAST 是个人的名字和姓氏,以及其他 25 列。

df.2X1X2 列,分别对应个人的名字和姓氏,以及其他 21 列。

我需要将df.1df.2 合并,并丢弃任何不在两个帧中的观察结果。

所以我现在应该有一个包含少于 875 个观察值和 48 列的数据框。

有什么建议吗?

谢谢

【问题讨论】:

  • 这在?merge 中有很好的记录,其中包括一个非常清晰的示例。
  • 默认情况下merge通过常用列名连接,重命名df2 colnames以匹配FIRSTLAST中的df.1

标签: r merge dataframe


【解决方案1】:

考虑到 df1 和 df2 的变量名称完全相同,您可以尝试

merge(df1, df2, by = c('X1', 'X2'), all = F)

在你的情况下,你需要

merge(df.1, df.2, by.x = c('FIRST', 'LAST'), by.y = c('X1', 'X2'))

对于提供的数据集:

library(XML)
url1 <- "http://stats.nhlnumbers.com/player_stats/year/2010"
df1 <- readHTMLTable(url1)
names <- data.frame(do.call(rbind, strsplit(as.character(df1[[1]][ ,1]),
                                            split = ", ")))
df1 <- cbind(df1, names)
#head(df1)

url2 <- "http://stats.nhlnumbers.com/player_stats/year/2009"
df2 <- readHTMLTable(url2)
names2 <- data.frame(do.call(rbind, strsplit(as.character(df2[[1]][ ,1]),
                                             split = ", ")))
df2 <- cbind(df2, names2)
#head(df2)

df1_2 <- merge(df1, df2, by = c('X1', 'X2'), all = F)
head(subset(df1_2, select = c('X1', 'X2', 'skaters-data.Name.x',
                              'NULL.PTS/$MM.x', 'NULL.PTS/$MM.y')))
df1_2$Player <- paste(df1_2$X2, df1_2$X1)
url3 <- "http://hockey-reference.com/leagues/NHL_2010_skaters.html"
df3 <- readHTMLTable(url3)
df3 <- as.data.frame(df3)

df4 <- merge(df1_2, df3, by.x = 'Player', by.y = 'stats.Player', all = F)
names(df4) <- gsub("[[:punct:]]", "_", names(df4))
head(subset(df4, select = c(X2, X1, Player, NULL_PTS__MM_x,
                            NULL_PTS__MM_y, stats_Rk)))

     X2      X1        Player NULL_PTS__MM_x NULL_PTS__MM_y stats_Rk
1 Aaron Johnson Aaron Johnson         18.519         15.573      344
2 Aaron    Rome    Aaron Rome          7.619          6.698      662
3 Aaron   Voros   Aaron Voros          7.000         16.000      825
4 Aaron    Ward    Aaron Ward          5.200          4.000      834
5  Adam  Burish   Adam Burish          5.614         12.632       95
6  Adam   Foote    Adam Foote          3.000          2.333      228

也许会画出来

df5 <- subset(df4, select = c(X2, X1, Player, NULL_PTS__MM_x,
                              NULL_PTS__MM_y, stats_Rk))[1:10, ]

library(ggplot2)
ggplot(aes(x = as.numeric(NULL_PTS__MM_x), y = as.numeric(stats_Rk),
       colour = Player), data = df5) +
  geom_point()

【讨论】:

  • 嘿,谢谢!但是,我一直在这条路上,它似乎不起作用。我可以获得所有变量但没有观察结果,或者通过使用 all.x 或 all.y 我可以获得所有的 obersvations 但 NA 的变量在 1 df 但不是另一个。我已经浏览了帮助文件,但我不明白是什么让这变得如此困难。我可以将我的代码通过电子邮件发送给任何人,以便我得到一些指导吗?
  • @KyleBillings 你能给我们提供一些真实的数据吗?
  • 'URL1 stats.nhlnumbers.com/player_stats/year/2010" tables.1 = readHTMLTable(URL1) table.1 = tables.1[[2]] URL2 stats.nhlnumbers.com/player_stats/year/2009" tables.2 = readHTMLTable (URL2) table.2 = tables.2[[1]] URL3 hockey-reference.com/leagues/NHL_2010_skaters.html" tables.3
  • @KyleBillings df.1 和 df.2 的 txt 或 csv 会很棒!
  • 刚才代码标记失败了。基本上我从 2010 年提取 NHL 工资数据和从 2009 年开始的球员统计数据。必须进行一些小的格式化,但后来我想将这两个数据框合并为一个。我在合并 nhl 数字数据(表 1 和 2)时没有问题,这是让我头疼的是曲棍球参考数据(表 3)
【解决方案2】:

除了base::merge,另一种选择是使用SQL

您可以在Rsqldf 中使用它(但将您的数据重命名为df1df2,不带点.

library(sqldf )
sqldf("SELECT *
      FROM df1, df2
      WHERE df1.FIRST==df2.X1
      and df1.LAST == df2.X2")

另一种选择是data.table,如果你有大数据集,你应该考虑这个:

library(data.table)
dt1 <- data.table(df1, key=c("FIRST", "LAST")) #set keys
dt2 <- data.table(df2, key=c("X1", "X2")) #set keys
dt1[dt2] #join

data.table 版本>= 1.9 开始,有一个函数setDT 通过引用将data.frame(以及list)转换为data.table。这将使事情变得更快,内存效率更高(尤其是在您的数据为 5GB 且您拥有 8GB RAM 的情况下)。所以,可以这样写:

require(data.table) # >= 1.9
setDT(df1) # df1 will be a data.table
setDT(df2) # df2 will be a data.table
setkey(df1, FIRST, LAST)
setkey(df2, X1, X2)
df1[df2]

【讨论】:

    猜你喜欢
    • 2019-05-01
    • 2022-01-25
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    相关资源
    最近更新 更多