【问题标题】:match vector against dataframe with multiple entries in R将向量与 R 中具有多个条目的数据帧匹配
【发布时间】:2013-07-18 15:43:03
【问题描述】:

我有以下两个数据框:

>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 元素关联的每个代码添加一列来反映这一点。

提前感谢您的任何建议。

【问题讨论】:

    标签: r merge match reshape


    【解决方案1】:

    这本质上是一个“从长到宽”的重塑问题,但您没有“时间”变量。您可以使用ave 加上seq_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
    

    【讨论】:

      【解决方案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 组合,但是使用这个包会更简单。

      【讨论】:

        猜你喜欢
        • 2020-09-13
        • 2015-12-19
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-01
        相关资源
        最近更新 更多