sql >> Databáze >  >> RDS >> Mysql

Reshape Table v MySQL nebo R

V základu R by funkce, která se má použít, byla reshape a převáděli byste svá data z „dlouhých“ na „široké“.

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>

Případně se můžete podívat na dcast z balíčku "reshape2" a zkuste:

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>

Pro vyšší rychlost převeďte data.frame do data.table a použijte dcast.data.table místo toho.

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

Z vašich komentářů to vypadá, že máte duplicitní hodnoty mezi kombinacemi sloupce 1 a 2, což znamená, že ve výchozím nastavení je dcast použije length jako jeho agregační funkci.

Abyste to překonali, musíte vytvořit sekundární sloupec ID (nebo vlastně „čas“), což lze provést takto.

Nejprve několik ukázkových dat. Všimněte si duplicitní kombinace prvních dvou sloupců v řádcích 1 a 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

Když vyzkoušíte dcast , pouze "počítá" číslo pod každou kombinací.

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

Buď se rozhodněte, který duplicitní řádek se má vypustit, nebo, pokud všechna data patří do vaší datové sady, přidejte proměnnou „time“, jako je tato:

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

Nyní dcast by měl fungovat dobře. Zde je polodlouhá verze...

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>

... a pološirokou verzi.

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>


  1. SQL - Jak najít nejvyšší číslo ve sloupci?

  2. Západka DBCC_OBJECT_METADATA

  3. Jak funguje Transaction_timestamp() v PostgreSQL

  4. executemany pro chybu MySQLdb pro velký počet řádků