我有以下两个数据帧:
>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元素相关联的每个代码包含一列来反映这一点。
提前感谢您提出任何建议。
答案 0 :(得分:3)
这实际上是一个“长到宽”的重塑问题,但你没有“时间”变量。您可以使用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
答案 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
组合之前制作相同长度的所有行,但使用此包会更简单。