我可以在dplyr中加入4个以上的数据帧吗?

时间:2016-06-10 16:52:09

标签: r left-join dplyr

我正在尝试将5个模型的结果合并到一个数据框中,以便使用dplyrleft_join进行演示。每个模型结果都存在于自己的数据框中(dat1到dat5用于演示目的)。

*这是家庭酿造似然函数的结果,因此没有可用于mtable包中的memiscstargazer中可用选项的摘要方法。

label1 <- paste0("var", 1:10)
beta1 <- 1:10
se1 <- 1:10*.01
p1 <- 1:10*.005

dat1 <- data.frame(label = label1
                   ,beta = beta1
                   ,se = se1
                   ,p = p1)


label2 <- paste0("var", 1:4)
beta2 <- 1:4
se2 <- 1:4*.01
p2 <- 1:4*.005

dat2 <- data.frame(label = label2
                   ,beta = beta2
                   ,se = se2
                   ,p = p2)


label3 <- paste0("var", 1:3)
beta3 <- 1:3
se3 <- 1:3*.01
p3 <- 1:3*.005

dat3 <- data.frame(label = label3
                   ,beta = beta3
                   ,se = se3
                   ,p = p3)

label4 <- paste0("var", 1:2)
beta4 <- 1:2
se4 <- 1:2*.01
p4 <- 1:2*.005

dat4 <- data.frame(label = label4
                   ,beta = beta4
                   ,se = se4
                   ,p = p4)

label5 <- paste0("var", 1)
beta5 <- 1
se5 <- 1*.01
p5 <- 1*.005

dat5 <- data.frame(label = label5
                   ,beta = beta5
                   ,se = se5
                   ,p = p5)

在常规SQL中,我希望LEFT JOIN函数的行为与sqldf中的行为相同,如下所示。

sqldf(
"
select * 
from dat1
  left join dat2
    on dat1.label = dat2.label
  left join dat3
    on dat1.label = dat3.label
  left join dat4
    on dat1.label = dat4.label
"
)

#label beta   se     p label beta   se     p label beta   se     p label beta   se     p
#1   var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005
#2   var2    2 0.02 0.010  var2    2 0.02 0.010  var2    2 0.02 0.010  var2    2 0.02 0.010
#3   var3    3 0.03 0.015  var3    3 0.03 0.015  var3    3 0.03 0.015  <NA>   NA   NA    NA
#4   var4    4 0.04 0.020  var4    4 0.04 0.020  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#5   var5    5 0.05 0.025  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#6   var6    6 0.06 0.030  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#7   var7    7 0.07 0.035  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#8   var8    8 0.08 0.040  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#9   var9    9 0.09 0.045  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#10 var10   10 0.10 0.050  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA

忽略常规SQL中重复的​​列标题,我可以在dplyr中复制相同的内容,如下所示。

dat1 %>% left_join(dat2,  by = c("label" = "label")) %>%
  left_join(dat3,  by = c("label" = "label")) %>%
  left_join(dat4,  by = c("label" = "label"))

#label beta.x se.x   p.x beta.y se.y   p.y beta.x se.x   p.x beta.y se.y   p.y
#1   var1      1 0.01 0.005      1 0.01 0.005      1 0.01 0.005      1 0.01 0.005
#2   var2      2 0.02 0.010      2 0.02 0.010      2 0.02 0.010      2 0.02 0.010
#3   var3      3 0.03 0.015      3 0.03 0.015      3 0.03 0.015     NA   NA    NA
#4   var4      4 0.04 0.020      4 0.04 0.020     NA   NA    NA     NA   NA    NA
#5   var5      5 0.05 0.025     NA   NA    NA     NA   NA    NA     NA   NA    NA
#6   var6      6 0.06 0.030     NA   NA    NA     NA   NA    NA     NA   NA    NA
#7   var7      7 0.07 0.035     NA   NA    NA     NA   NA    NA     NA   NA    NA
#8   var8      8 0.08 0.040     NA   NA    NA     NA   NA    NA     NA   NA    NA
#9   var9      9 0.09 0.045     NA   NA    NA     NA   NA    NA     NA   NA    NA
#10 var10     10 0.10 0.050     NA   NA    NA     NA   NA    NA     NA   NA    NA

在常规SQL中,我可以在混合中添加第5个表并获得预期结果。

sqldf(
  "
select * 
from dat1
  left join dat2
    on dat1.label = dat2.label
  left join dat3
    on dat1.label = dat3.label
  left join dat4
    on dat1.label = dat4.label
  left join dat5
    on dat1.label = dat5.label
"
)

#label beta   se     p label beta   se     p label beta   se     p label beta   se     p label beta   se     p
#1   var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005
#2   var2    2 0.02 0.010  var2    2 0.02 0.010  var2    2 0.02 0.010  var2    2 0.02 0.010  <NA>   NA   NA    NA
#3   var3    3 0.03 0.015  var3    3 0.03 0.015  var3    3 0.03 0.015  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#4   var4    4 0.04 0.020  var4    4 0.04 0.020  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#5   var5    5 0.05 0.025  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#6   var6    6 0.06 0.030  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#7   var7    7 0.07 0.035  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#8   var8    8 0.08 0.040  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#9   var9    9 0.09 0.045  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#10 var10   10 0.10 0.050  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA

dplyr中,虽然我似乎加入了dat5,但我最终放弃了dat3dat4,并重复了dat1和{{的结果1}}。

dat2

我是否正确将联接移至dat1 %>% left_join(dat2, by = c("label" = "label")) %>% left_join(dat3, by = c("label" = "label")) %>% left_join(dat4, by = c("label" = "label")) %>% left_join(dat5, by = c("label" = "label")) #label beta.x se.x p.x beta.y se.y p.y beta.x se.x p.x beta.y se.y p.y beta se p #1 var1 1 0.01 0.005 1 0.01 0.005 1 0.01 0.005 1 0.01 0.005 1 0.01 0.005 #2 var2 2 0.02 0.010 2 0.02 0.010 2 0.02 0.010 2 0.02 0.010 NA NA NA #3 var3 3 0.03 0.015 3 0.03 0.015 3 0.03 0.015 3 0.03 0.015 NA NA NA #4 var4 4 0.04 0.020 4 0.04 0.020 4 0.04 0.020 4 0.04 0.020 NA NA NA #5 var5 5 0.05 0.025 NA NA NA 5 0.05 0.025 NA NA NA NA NA NA #6 var6 6 0.06 0.030 NA NA NA 6 0.06 0.030 NA NA NA NA NA NA #7 var7 7 0.07 0.035 NA NA NA 7 0.07 0.035 NA NA NA NA NA NA #8 var8 8 0.08 0.040 NA NA NA 8 0.08 0.040 NA NA NA NA NA NA #9 var9 9 0.09 0.045 NA NA NA 9 0.09 0.045 NA NA NA NA NA NA #10 var10 10 0.10 0.050 NA NA NA 10 0.10 0.050 NA NA NA NA NA NA 中的dat5

是否可以在dplyr中执行这么多连接?

EDIT1:我认为这与(How to perform multiple left joins using dplyr in R)截然不同。 dplyr似乎解决了那里概述的问题。

就我而言,Reduce产生的结果与我上一个代码块中显示的结果相同。

EDIT2:要清楚,我并不关心多重左连接语法。我试图确定为什么超过4个连接的行为不像他们在&#34;常规&#34; SQL。

编辑3:虽然我最初接受了@akrun的答案,但我现在意识到以下输出:

Reduce

仍然与

不同
lst <- lapply(mget(paste0("dat", 1:5)), transform, label2 = label)
suppressWarnings( Reduce(function(...) left_join(..., by = "label"), lst))

#label beta.x se.x   p.x label2.x beta.y se.y   p.y label2.y beta.x se.x   p.x label2.x beta.y se.y   p.y label2.y beta   se     p label2
#1   var1      1 0.01 0.005     var1      1 0.01 0.005     var1      1 0.01 0.005     var1      1 0.01 0.005     var1    1 0.01 0.005   var1
#2   var2      2 0.02 0.010     var2      2 0.02 0.010     var2      2 0.02 0.010     var2      2 0.02 0.010     var2   NA   NA    NA   <NA>
#  3   var3      3 0.03 0.015     var3      3 0.03 0.015     var3      3 0.03 0.015     var3      3 0.03 0.015     var3   NA   NA    NA   <NA>
#  4   var4      4 0.04 0.020     var4      4 0.04 0.020     var4      4 0.04 0.020     var4      4 0.04 0.020     var4   NA   NA    NA   <NA>
#  5   var5      5 0.05 0.025     var5     NA   NA    NA     <NA>      5 0.05 0.025     var5     NA   NA    NA     <NA>   NA   NA    NA   <NA>
#  6   var6      6 0.06 0.030     var6     NA   NA    NA     <NA>      6 0.06 0.030     var6     NA   NA    NA     <NA>   NA   NA    NA   <NA>
#  7   var7      7 0.07 0.035     var7     NA   NA    NA     <NA>      7 0.07 0.035     var7     NA   NA    NA     <NA>   NA   NA    NA   <NA>
#  8   var8      8 0.08 0.040     var8     NA   NA    NA     <NA>      8 0.08 0.040     var8     NA   NA    NA     <NA>   NA   NA    NA   <NA>
#  9   var9      9 0.09 0.045     var9     NA   NA    NA     <NA>      9 0.09 0.045     var9     NA   NA    NA     <NA>   NA   NA    NA   <NA>
#  10 var10     10 0.10 0.050    var10     NA   NA    NA     <NA>     10 0.10 0.050    var10     NA   NA    NA     <NA>   NA   NA    NA   <NA>

我仍在失去sqldf( " select * from dat1 left join dat2 on dat1.label = dat2.label left join dat3 on dat1.label = dat3.label left join dat4 on dat1.label = dat4.label left join dat5 on dat1.label = dat5.label " ) #label beta se p label beta se p label beta se p label beta se p label beta se p #1 var1 1 0.01 0.005 var1 1 0.01 0.005 var1 1 0.01 0.005 var1 1 0.01 0.005 var1 1 0.01 0.005 #2 var2 2 0.02 0.010 var2 2 0.02 0.010 var2 2 0.02 0.010 var2 2 0.02 0.010 <NA> NA NA NA #3 var3 3 0.03 0.015 var3 3 0.03 0.015 var3 3 0.03 0.015 <NA> NA NA NA <NA> NA NA NA #4 var4 4 0.04 0.020 var4 4 0.04 0.020 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA #5 var5 5 0.05 0.025 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA #6 var6 6 0.06 0.030 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA #7 var7 7 0.07 0.035 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA #8 var8 8 0.08 0.040 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA #9 var9 9 0.09 0.045 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA #10 var10 10 0.10 0.050 <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA <NA> NA NA NA dat3 ...

编辑4:不确定原因,但我的混淆可能部分是版本问题。 @ akrun的最终答案适用于dat4dplyr_0.4.3(显然是Linux(Ubuntu)和PC)。

编辑5:我认为@akrun和我都在运行R version 3.3.0的开发版本(这就是为什么我首先遇到问题在我的Windows机器上运行@ akrun&#39的解决方案生产dplyr。)如上所述[{3}},此问题已在dplyr的最新开发版本中得到解决。

1 个答案:

答案 0 :(得分:1)

将数据集放入Reduce后,我们可以将left_joinlist一起使用。

Reduce(function(...) left_join(..., by = "label"), mget(paste0("dat", 1:5)))

如果我们需要label列,我们可以再创建一列

lst <- lapply(mget(paste0("dat", 1:5)), transform, label2 = label)
lst[[1]]["label2"] <- NULL
res1 <- suppressWarnings( Reduce(function(...) left_join(..., by = "label"), lst))
res1
#   label beta.x se.x   p.x beta.y se.y   p.y label2.x beta.x.x se.x.x p.x.x label2.y beta.y.y se.y.y p.y.y label2.x.x beta   se     p
#1   var1      1 0.01 0.005      1 0.01 0.005     var1        1   0.01 0.005     var1        1   0.01 0.005       var1    1 0.01 0.005
#2   var2      2 0.02 0.010      2 0.02 0.010     var2        2   0.02 0.010     var2        2   0.02 0.010       var2   NA   NA    NA
#3   var3      3 0.03 0.015      3 0.03 0.015     var3        3   0.03 0.015     var3       NA     NA    NA       <NA>   NA   NA    NA
#4   var4      4 0.04 0.020      4 0.04 0.020     var4       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#5   var5      5 0.05 0.025     NA   NA    NA     <NA>       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#6   var6      6 0.06 0.030     NA   NA    NA     <NA>       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#7   var7      7 0.07 0.035     NA   NA    NA     <NA>       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#8   var8      8 0.08 0.040     NA   NA    NA     <NA>       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#9   var9      9 0.09 0.045     NA   NA    NA     <NA>       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#10 var10     10 0.10 0.050     NA   NA    NA     <NA>       NA     NA    NA     <NA>       NA     NA    NA       <NA>   NA   NA    NA
#   label2.y.y
#1        var1
#2        <NA>
#3        <NA>
#4        <NA>
#5        <NA>
#6        <NA>
#7        <NA>
#8        <NA>
#9        <NA>
#10       <NA>

以下是第二个sqldf代码块

的OP输出
res2
#   label beta   se     p label beta   se     p label beta   se     p label beta   se     p label beta   se     p
#1   var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005  var1    1 0.01 0.005
#2   var2    2 0.02 0.010  var2    2 0.02 0.010  var2    2 0.02 0.010  var2    2 0.02 0.010  <NA>   NA   NA    NA
#3   var3    3 0.03 0.015  var3    3 0.03 0.015  var3    3 0.03 0.015  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#4   var4    4 0.04 0.020  var4    4 0.04 0.020  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#5   var5    5 0.05 0.025  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#6   var6    6 0.06 0.030  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#7   var7    7 0.07 0.035  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#8   var8    8 0.08 0.040  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#9   var9    9 0.09 0.045  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA
#10 var10   10 0.10 0.050  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA  <NA>   NA   NA    NA


dim(res1)
#[1] 10 20
dim(res2)
#[1] 10 20