合并R中的数据

时间:2014-03-18 21:36:53

标签: r merge

我有一个数据集A

paper_id author_id
  1       521630
  1       1611750
  2       9
  3       627950
  4       1456512
  8       15
  ........

和数据集B

author_id    author_name        author_affiliation
    9       Ernest Jordan            Cambridge                                                    
    14         K. MORIBE               NA                                                 
    15     D. Jakominich               NA                                                 
    25     William H. Nailon                                                                
    37     P. B. Littlewood    Cavendish Laboratory|Cambridge University 
    ........       

我想以这样的方式合并这两个数据集,以便通过author_id完成合并,但结果应该看起来像:

paper id    author_id        author_name     author_affiliation
  2            9             Ernest Jordan     Cambridge
  8            15            D. Jakominich       NA

那就是我想只通过paper_id按顺序获取数据,并在author_id上执行合并,这样所有的paper_id顺序都不会受到干扰。

我正在做的是:

b<-merge(A,B,by="author_id")

我正在接受。在这方面,paper_id受到了干扰

 author_id paper_id       author_name      author_affiliation
     9     1468598       Ernest Jordan       cambridge
     9     1682105       Ernest Jordan       cambridge

然后我必须通过对paper_id列进行排序来对此输出进行排序。这是一种非常低效的方式。

怎么可能这样做。

由于

3 个答案:

答案 0 :(得分:2)

这应该做你想要的。

b <-merge(A,B,by="author_id", sort=F)
b <- b[,c(2,1,3,4)]

您可以使用by=...关闭sort=F列的排序,但merge(...)始终会将排序列作为结果的第一列。最后一行代码只是反转了第1列和第2列。

编辑(对@BrianDiggs评论的回复)

@BrianDiggs是正确的,虽然sort=F不会对by=...列强制排序,但它不保证A中的原始排序顺序。如果效率是一个大问题,那么请考虑为此构建的data.table包:

# create an example
A <- data.frame(paper_id=1:10000, author_id=rev(LETTERS[1:4]))
B <- data.frame(author_id=LETTERS[1:4],
                author_name=c("Davies","Hawking","Carlyle","Higgs"),
                author_affiliation=c("Oxford","Cambridge","UCL","Edinburgh"),
                stringsAsFactors=F)

library(data.table)
A <- data.table(A,key="author_id")
B <- data.table(B,key="author_id")
A[B,c("author_name","author_affiliation"):=list(author_name,author_affiliation)]
setkey(A,paper_id)
head(A)
#    paper_id author_id author_name author_affiliation
# 1:        1         D       Higgs          Edinburgh
# 2:        2         C     Carlyle                UCL
# 3:        3         B     Hawking          Cambridge
# 4:        4         A      Davies             Oxford
# 5:        5         D       Higgs          Edinburgh
# 6:        6         C     Carlyle                UCL

sort(...)不同,在数据表中设置一个键可以通过引用&#34;进行排序。使用基数算法。按引用排序意味着行重新排列在内存中,而不是将整个表复制到新表中。因此,对数据表进行排序非常快且内存效率高。

此外,使用A[B,...]进行合并要比合并两个数据帧快得多。此外,此流程将新列附加到A(而不是像merge(...)一样创建A的副本。

答案 1 :(得分:1)

如果您可以考虑非base替代方案,那么您可以尝试plyr相当于mergejoin。来自?join中的“详细信息”:Unlike merge, preserves the order of x no matter what join type is used.。还保留了列的顺序。

library(plyr)
join(A, B, type = "inner")
# Joining by: author_id
#   paper_id author_id  author_name author_affiliation
# 1        2         9 ErnestJordan          Cambridge
# 2        8        15   Jakominich               <NA>
inner_join中的

dplyr类似。但是,虽然保留了x中列的顺序,但y中的列似乎按字母顺序排序:

library(dplyr)
inner_join(x = A, y = B)
# Joining by: "author_id"
#   paper_id author_id author_affiliation  author_name
# 1        2         9          Cambridge ErnestJordan
# 2        8        15               <NA>   Jakominich

答案 2 :(得分:0)

评论太长

我确实得到了你想要的东西:

A <- read.table(text="paper_id author_id
1       521630
1       1611750
2       9
3       627950
4       1456512
8       15", header=T)

B <- read.table(text="author_id  author_name author_affiliation
9       Ernest_Jordan            Cambridge
14         K._MORIBE               NA
15     D._Jakominich               NA
25     William_H._Nailon           NA
37     P._B._Littlewood    Cavendish_Laboratory|Cambridge_University", 
header=T)

b <- merge(A, B, by="author_id")
b
#   author_id paper_id   author_name author_affiliation
# 1         9        2 Ernest_Jordan          Cambridge
# 2        15        8 D._Jakominich               <NA>

你能澄清一下你的问题吗?