如何在R中以匹配条件在两列数据帧之间插入一列?

时间:2016-08-19 19:13:03

标签: r

我有两个数据框,

DF1

 Identifier    GSE1028888  GSE1034555
     100002           0.1         0.2
     100003           0.3         0.4
     ......         .....       .....
     100007           0.9         1.1

DF2

         V3            V2
     100002         XLX12         
     100003         ABorF        
     ......         .....       
     110000         GEF22

现在我想将V2信息插入df1,例如

DF3

 Identifier        New_V2    GSE1028888  GSE1034555
     100002         XLX12           0.1         0.2
     100003         ABorF           0.3         0.4
     100004            NA           0.6         0.7
     ......         .....       .....
     100007         ccL34           0.9         1.1           

df2的V3和df1的标识符具有不同的长度。 我尝试使用dplyr left_join,但最后附上了该列。

这是创建类似数据框的代码

df1 <- data.frame("Identifier" = sample(100001:100010, 6, replace = F), 
               y = sample(rnorm(10), 6, replace = T), 
               z = sample(rnorm(10), 6, replace = T))
df2 <- data.frame(V1 = c(100001:100010), 
              V2 = sample(state.name, 10, replace = T))

这次我尝试使用dplyr left_join,

left_join(df1, df2, by =c("Identifier"="V3"))

显示错误消息

Error: cannot join on columns 'V3' x 'Identifier': index out of bounds

任何人都有任何想法?

2 个答案:

答案 0 :(得分:4)

一种解决方案是合并并重新排序它们(遗憾的是不是单功能答案)。

<强>设置

df1 = data.frame(i=c(1,2,3), GSE111=c(4,5,6), GSE222=c(7,8,9))
df2 = data.frame(i=c(1,3,4), v2=c(10,11,12))

这会产生:

> df1
  i GSE111 GSE222
1 1      4      7
2 2      5      8
3 3      6      9
4 4      7     10

> df2
  i v2
1 1 10
2 3 11
3 4 12

<强>合并:

我使用了内置的合并功能而不是plyr。

df3 = merge(x=df1, y=df2, by="i", all.x=TRUE)

这将产生:

  i GSE111 GSE222 v2
1 1      4      7 10
2 2      5      8 NA
3 3      6      9 11

<强>重排:

现在您可以通过字面输入列名来重新排序:

df4 = df3[,c("i", "v2", "GSE111", "GSE222")]

产生

  i v2 GSE111 GSE222
1 1 10      4      7
2 2 NA      5      8
3 3 11      6      9

这基本上就是您想要的产品。

<强>快捷方式:

或者,如果你像我一样懒,我可以在df1和df2之间生成唯一的列名,如下所示:

unique(c(colnames(df2), colnames(df1)))

这会产生:

[1] "i"      "v2"     "GSE111" "GSE222"

所以你可以输入类似的内容:

df3[,unique(c(colnames(df2), colnames(df1)))]

答案 1 :(得分:1)

使用您提供的数据:

df1 <- data.frame("Identifier" = sample(100001:100010, 6, replace = F), 
               y = sample(rnorm(10), 6, replace = T), 
               z = sample(rnorm(10), 6, replace = T))
df2 <- data.frame(V1 = c(100001:100010), 
              V2 = sample(state.name, 10, replace = T))

merge(df2, df1, by.x="V1",by.y="Identifier", all.x=TRUE)
       V1            V2          y          z
1  100001     Wisconsin -1.9468637  0.4509951
2  100002      Nebraska  2.5155819  0.4509951
3  100003          Ohio         NA         NA
4  100004 Massachusetts         NA         NA
5  100005       Montana -1.9468637 -2.1825878
6  100006      Illinois -0.1591367  0.3445637
7  100007    New Mexico -0.5696300  0.4509951
8  100008    New Jersey         NA         NA
9  100009     Tennessee         NA         NA
10 100010    Washington -1.9468637 -0.5402241

你可以切换你喜欢的顺序,但上面的输出是你要求的 - 无需重新排序但是如果想要:

merge(df2, df1, by.x="V1",by.y="Identifier", all.x=TRUE)[c(2,3,4,1)]
              V2          y          z     V1
1      Wisconsin -1.9468637  0.4509951 100001
2       Nebraska  2.5155819  0.4509951 100002
3           Ohio         NA         NA 100003
4  Massachusetts         NA         NA 100004
5        Montana -1.9468637 -2.1825878 100005
6       Illinois -0.1591367  0.3445637 100006
7     New Mexico -0.5696300  0.4509951 100007
8     New Jersey         NA         NA 100008
9      Tennessee         NA         NA 100009
10    Washington -1.9468637 -0.5402241 100010

根据OP发布的评论,下面是df1中存在df2中不存在的标识符的示例

df1 <- data.frame("Identifier" = sample(100001:100012, 6, replace = F), 
               y = sample(rnorm(10), 6, replace = T), 
               z = sample(rnorm(10), 6, replace = T))

df1
  Identifier           y            z
1     100011 -1.60532712  1.365836073
2     100007 -1.28821500  0.005925986
3     100004 -0.03444609  0.780708952
4     100006  0.32190045  0.780708952
5     100009 -1.60532712 -1.471916384
6     100005 -0.76985033  0.191956916

df2 <- data.frame(V1 = c(100001:100010), 
              V2 = sample(state.name, 10, replace = T))
df2
       V1            V2
1  100001  Pennsylvania
2  100002 West Virginia
3  100003          Utah
4  100004        Alaska
5  100005          Ohio
6  100006   Mississippi
7  100007 New Hampshire
8  100008    New Jersey
9  100009          Ohio
10 100010       Georgia

merge(df2, df1, by.x="V1",by.y="Identifier", all.x=TRUE, all.y=TRUE)
       V1            V2           y            z
1  100001  Pennsylvania          NA           NA
2  100002 West Virginia          NA           NA
3  100003          Utah          NA           NA
4  100004        Alaska -0.03444609  0.780708952
5  100005          Ohio -0.76985033  0.191956916
6  100006   Mississippi  0.32190045  0.780708952
7  100007 New Hampshire -1.28821500  0.005925986
8  100008    New Jersey          NA           NA
9  100009          Ohio -1.60532712 -1.471916384
10 100010       Georgia          NA           NA
11 100011          <NA> -1.60532712  1.365836073