合并两个数据帧,同时保持原始行顺序

DJa*_*ack 55 sorting merge r dataframe

我想合并两个数据帧,保持其中一个的原始行顺序(df.2在下面的示例中).

以下是一些示例数据(class列中的所有值都在两个数据框中定义):

df.1 <- data.frame(class = c(1, 2, 3), prob = c(0.5, 0.7, 0.3))
df.2 <- data.frame(object = c('A', 'B', 'D', 'F', 'C'), class = c(2, 1, 2, 3, 1))
Run Code Online (Sandbox Code Playgroud)

如果我做:

merge(df.2, df.1)
Run Code Online (Sandbox Code Playgroud)

输出是:

  class object prob
1     1      B  0.5
2     1      C  0.5
3     2      A  0.7
4     2      D  0.7
5     3      F  0.3
Run Code Online (Sandbox Code Playgroud)

如果我添加sort = FALSE:

merge(df.2, df.1, sort = F)                                                        
Run Code Online (Sandbox Code Playgroud)

结果是:

  class object prob
1     2      A  0.7
2     2      D  0.7
3     1      B  0.5
4     1      C  0.5
5     3      F  0.3
Run Code Online (Sandbox Code Playgroud)

但我想要的是:

  class object prob
1     2      A  0.7
2     1      B  0.5
3     2      D  0.7
4     3      F  0.3    
5     1      C  0.5
Run Code Online (Sandbox Code Playgroud)

PAC*_*PAC 45

您只需要创建一个变量,该变量在df.2中给出行号.然后,一旦合并了数据,就可以根据此变量对新数据集进行排序.这是一个例子:

df.1<-data.frame(class=c(1,2,3), prob=c(0.5,0.7,0.3))
df.2<-data.frame(object=c('A','B','D','F','C'), class=c(2,1,2,3,1))
df.2$id  <- 1:nrow(df.2)
out  <- merge(df.2,df.1, by = "class")
out[order(out$id), ]
Run Code Online (Sandbox Code Playgroud)


小智 30

查看plyr包中的join函数.它就像合并,但它允许您保持其中一个数据集的行顺序.总的来说,它比合并更灵活.

使用您的示例数据,我们将使用join如下:

> join(df.2,df.1)
Joining by: class
  object class prob
1      A     2  0.7
2      B     1  0.5
3      D     2  0.7
4      F     3  0.3
5      C     1  0.5
Run Code Online (Sandbox Code Playgroud)

以下是一些描述合并函数修复的链接,用于保持行顺序:

http://www.r-statistics.com/2012/01/merging-two-data-frame-objects-while-preserving-the-rows-order/

http://r.789695.n4.nabble.com/patching-merge-to-allow-the-user-to-keep-the-order-of-one-of-the-two-data-frame-objects-合并后,td4296561.html

  • 在这里展示解决方案,而不仅仅是引用它们。链接在互联网上很快就会失效。 (2认同)
  • 我(以及`join`s documentation)会不同意它比`merge`"更灵活":"Join通常比merge更快,虽然它的功能稍差 - 它目前无法重命名输出或合并不同x和y数据框中的变量." (2认同)

Aru*_*run 11

data.table v1.9.5 +,您可以:

require(data.table) # v1.9.5+
setDT(df.1)[df.2, on="class"]
Run Code Online (Sandbox Code Playgroud)

在执行一上柱加入class通过在找出匹配的行df.1中每一行df.2和提取对应的列.


ale*_*emm 9

您还可以查看inner_joinHadley dplyr包中的函数(下一次迭代plyr).它保留第一个数据集的行顺序.与您所需解决方案的细微差别在于它还保留了第一个数据集的原始列顺序.因此,它不一定将我们用于合并的列放在第一个位置.

使用上面的示例,inner_join结果如下所示:

inner_join(df.2,df.1)
Joining by: "class"
  object class prob
1      A     2  0.7
2      B     1  0.5
3      D     2  0.7
4      F     3  0.3
5      C     1  0.5
Run Code Online (Sandbox Code Playgroud)


Uwe*_*Uwe 5

为了完整起见,连接中的更新也会保留原始行顺序.如果只有几列要追加,这可能是Arun data.table答案的替代方案:

library(data.table)
setDT(df.2)[df.1, on = "class", prob := i.prob][]
Run Code Online (Sandbox Code Playgroud)
   object class prob
1:      A     2  0.7
2:      B     1  0.5
3:      D     2  0.7
4:      F     3  0.3
5:      C     1  0.5
Run Code Online (Sandbox Code Playgroud)

在这里,df.2正确连接df.1并获得一个新列prob,该列从匹配的行中复制df.1.