匹配带有R中多个条目的数据帧的向量

时间:2013-07-18 15:43:04

标签: r merge match reshape

我有以下两个数据帧:

>df1<-data.frame(ID=c(111,222,333,444))
   ID
1 111
2 222
3 333
4 444

>df2<-data.frame(ID=c(111,111,111,222,333,333,444,444,444,444,444,444),CODE=c(1,1,2,3,2,3,4,5,2,3,4,5))
    ID CODE
1  111    1
2  111    1
3  111    2
4  222    3
5  333    2
6  333    3
7  444    4
8  444    5
9  444    2
10 444    3
11 444    4
12 444    5

并希望将df1中的ID元素与df2中的ID元素进行匹配,以生成第三个如下所示的数据框:

> df3<-data.frame(ID=c(111,222,333,444),CODE1=c(1,3,2,4),CODE2=c(1,NA,3,5),CODE3=c(2,NA,NA,2),CODE4=c(NA,NA,NA,3),CODE5=c(NA,NA,NA,4),CODE6=c(NA,NA,NA,5))
   ID CODE1 CODE2 CODE3 CODE4 CODE5 CODE6
1 111     1     1     2    NA    NA    NA
2 222     3    NA    NA    NA    NA    NA
3 333     2     3    NA    NA    NA    NA
4 444     4     5     2     3     4     5

请注意,df2包含df1中多个ID元素的多个代码。我希望df3通过为与ID元素相关联的每个代码包含一列来反映这一点。

提前感谢您提出任何建议。

2 个答案:

答案 0 :(得分:3)

这实际上是一个“长到宽”的重塑问题,但你没有“时间”变量。您可以使用aveseq_along创建一个,如下所示:

df2$TIME <- ave(df2$ID, df2$ID, FUN = seq_along)
df2
#     ID CODE TIME
# 1  111    1    1
# 2  111    1    2
# 3  111    2    3
# 4  222    3    1
# 5  333    2    1
# 6  333    3    2
# 7  444    4    1
# 8  444    5    2
# 9  444    2    3
# 10 444    3    4
# 11 444    4    5
# 12 444    5    6

现在,您可以轻松使用基础R reshape ....

reshape(df2, direction = "wide", idvar = "ID", timevar = "TIME")
#    ID CODE.1 CODE.2 CODE.3 CODE.4 CODE.5 CODE.6
# 1 111      1      1      2     NA     NA     NA
# 4 222      3     NA     NA     NA     NA     NA
# 5 333      2      3     NA     NA     NA     NA
# 7 444      4      5      2      3      4      5
来自“reshape2”的

...或dcast

library(reshape2)
dcast(df2, ID ~ TIME, value.var="CODE")
#    ID 1  2  3  4  5  6
# 1 111 1  1  2 NA NA NA
# 2 222 3 NA NA NA NA NA
# 3 333 2  3 NA NA NA NA
# 4 444 4  5  2  3  4  5

答案 1 :(得分:2)

您可以使用plyr package中的ddply功能执行任务:

> ddply(df2, .(ID), function (d) { t(d$CODE) })
     ID 1  2  3  4  5  6
  1 111 1  1  2 NA NA NA
  2 222 3 NA NA NA NA NA
  3 333 2  3 NA NA NA NA
  4 444 4  5  2  3  4  5

可以使用by来获取行,然后使用一些聪明的技巧在将它们与rbind组合之前制作相同长度的所有行,但使用此包会更简单。