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

提前感谢您的任何和所有建议。

4

2 回答 2

3

这本质上是一个“从长到宽”的重塑问题,但您没有“时间”变量。您可以使用aveplusseq_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
于 2013-07-18T16:52:52.393 回答
2

您可以使用ddply中的功能来完成任务:plyr

> 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,但使用这个包会更简单。

于 2013-07-18T15:53:38.313 回答