首页 文章

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

提问于
浏览
2

我有以下两个数据帧:

>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 回答

  • 3

    这本质上是一个重塑问题,但你没有"time"变量 . 您可以使用 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
    

    ...或 dcast 来自"reshape2"

    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
    
  • 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 组合之前制作相同长度的所有行,但使用此包会更简单 .

相关问题