sql >> Base de Datos >  >> RDS >> Mysql

Reformar tabla en MySQL o R

En base R, la función a usar sería reshape , y estaría convirtiendo sus datos de "largos" a "anchos".

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>

Alternativamente, puede mirar dcast del paquete "reshape2" e intente:

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>

Para una mejor velocidad, convierta su data.frame a una data.table y use dcast.data.table en su lugar.

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

Según sus comentarios, parece que tiene valores duplicados entre las combinaciones de las columnas 1 y 2, lo que significa que, de forma predeterminada, dcast utilizará length como su función de agregación.

Para superar esto, debe crear una columna de ID secundaria (o "tiempo", en realidad), que se puede hacer así.

Primero, algunos datos de muestra. Tenga en cuenta la combinación duplicada de las dos primeras columnas en las filas 1 y 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

Cuando intentas dcast , simplemente "cuenta" el número debajo de cada combinación.

## 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

Decida qué fila duplicada debe eliminarse o, si todos los datos pertenecen a su conjunto de datos, agregue una variable de "tiempo", como esta:

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

Ahora, dcast debería funcionar bien Aquí hay una versión semilarga...

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>

... y una versión semi-ancha.

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>