Di basis R, fungsi yang akan digunakan adalah reshape
, dan Anda akan mengonversi data dari "panjang" menjadi "lebar".
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>
Atau, Anda dapat melihat dcast
dari paket "reshape2" dan coba:
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>
Untuk kecepatan yang lebih baik, konversikan data.frame
Anda ke data.table
dan gunakan dcast.data.table
sebagai gantinya.
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
Dari komentar Anda, sepertinya Anda memiliki nilai duplikat di antara kombinasi kolom 1 dan 2, yang berarti bahwa secara default, dcast
akan menggunakan length
sebagai fungsi agregasinya.
Untuk melewati ini, Anda perlu membuat kolom ID sekunder (atau "waktu", sebenarnya), yang dapat dilakukan seperti ini.
Pertama, beberapa sampel data. Perhatikan kombinasi duplikat dari dua kolom pertama di baris 1 dan 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
Saat Anda mencoba dcast
, itu hanya "menghitung" angka di bawah setiap kombinasi.
## 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
Putuskan baris duplikat mana yang harus dibuang, atau, jika semua data termasuk dalam kumpulan data Anda, tambahkan variabel "waktu", seperti ini:
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
Sekarang, dcast
harus bekerja dengan baik. Ini versi setengah panjangnya...
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>
... dan versi semi-lebar.
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>