I bas R skulle funktionen som ska användas vara reshape
, och du skulle konvertera din data från "lång" till "bred".
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>
Alternativt kan du titta på dcast
från paketet "reshape2" och försök:
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>
För bättre hastighet, konvertera din data.frame
till en data.table
och använd dcast.data.table
istället.
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
Från dina kommentarer låter det som att du har dubblerade värden bland kombinationerna av kolumn 1 och 2, vilket betyder att som standard, dcast
kommer att använda length
som dess aggregeringsfunktion.
För att komma förbi detta måste du skapa en sekundär ID (eller "tid", faktiskt) kolumn, vilket kan göras så här.
Först några exempeldata. Notera den dubblerade kombinationen av de två första kolumnerna i rad 1 och 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
När du försöker dcast
, det "räknas" bara antalet under varje kombination.
## 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
Bestäm antingen vilken dubblerad rad som ska tas bort, eller, om all data hör hemma i din datauppsättning, lägg till en "tid"-variabel, så här:
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
Nu, dcast
borde fungera bra. Här är en halvlång version...
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>
... och en halvbred version.
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>