在基本 R 中,要使用的函数是 reshape,您会将数据从“长”转换为“宽”。
reshape(mydf, direction = "wide", idvar="perid", timevar="date")
# perid rating.2005 rating.2006 rating.2007 rating.2008 rating.2009 rating.2010 rating.2011
# 1 10001 RD GN GD <NA> <NA> <NA> <NA>
# 4 10002 <NA> <NA> <NA> GD YW GN GN
# 8 10003 GD GN YW <NA> <NA> <NA> <NA>
或者,您可以查看“reshape2”包中的dcast 并尝试:
library(reshape2)
dcast(mydf, perid ~ date, value.var="rating")
# perid 2005 2006 2007 2008 2009 2010 2011
# 1 10001 RD GN GD <NA> <NA> <NA> <NA>
# 2 10002 <NA> <NA> <NA> GD YW GN GN
# 3 10003 GD GN YW <NA> <NA> <NA> <NA>
为了提高速度,请将您的 data.frame 转换为 data.table 并改用 dcast.data.table。
library(reshape2)
library(data.table)
DT <- data.table(mydf)
dcast.data.table(DT, perid ~ date, value.var = "rating")
# perid 2005 2006 2007 2008 2009 2010 2011
# 1: 10001 RD GN GD NA NA NA NA
# 2: 10002 NA NA NA GD YW GN GN
# 3: 10003 GD GN YW NA NA NA NA
从您的 cmets 看来,您在第 1 列和第 2 列的组合中有重复值,这意味着默认情况下,dcast 将使用length 作为其聚合函数。
要解决这个问题,您需要创建一个辅助 ID(实际上是“时间”)列,可以这样完成。
首先,一些示例数据。请注意第 1 行和第 2 行中前两列的重复组合。
mydf <- data.frame(
period = c(10001, 10001, 10002, 10002, 10003, 10003, 10001, 10001),
date = c(2005, 2005, 2006, 2007, 2005, 2006, 2006, 2007),
rating = c("RD", "GN", "GD", "GD", "YW", "GN", "GD", "YN"))
mydf
# period date rating
# 1 10001 2005 RD
# 2 10001 2005 GN
# 3 10002 2006 GD
# 4 10002 2007 GD
# 5 10003 2005 YW
# 6 10003 2006 GN
# 7 10001 2006 GD
# 8 10001 2007 YN
当您尝试dcast 时,它只会“计算”每个组合下的数字。
## Not what you want
dcast(mydf, period ~ date, value.var="rating")
# Aggregation function missing: defaulting to length
# period 2005 2006 2007
# 1 10001 2 1 1
# 2 10002 0 1 1
# 3 10003 1 1 0
要么决定应该删除哪个重复行,要么,如果所有数据都属于您的数据集中,则添加一个“时间”变量,如下所示:
mydf$time <- ave(1:nrow(mydf), mydf$period, mydf$date, FUN = seq_along)
mydf
# period date rating time
# 1 10001 2005 RD 1
# 2 10001 2005 GN 2
# 3 10002 2006 GD 1
# 4 10002 2007 GD 1
# 5 10003 2005 YW 1
# 6 10003 2006 GN 1
# 7 10001 2006 GD 1
# 8 10001 2007 YN 1
现在,dcast 应该可以正常工作了。这是一个半长版本...
dcast(mydf, period + time ~ date, value.var="rating")
# period time 2005 2006 2007
# 1 10001 1 RD GD YN
# 2 10001 2 GN <NA> <NA>
# 3 10002 1 <NA> GD GD
# 4 10003 1 YW GN <NA>
...和半宽版本。
dcast(mydf, period ~ date + time, value.var="rating")
# period 2005_1 2005_2 2006_1 2007_1
# 1 10001 RD GN GD YN
# 2 10002 <NA> <NA> GD GD
# 3 10003 YW <NA> GN <NA>