【问题标题】:Reshape Table in MySQL or R [duplicate]在 MySQL 或 R 中重塑表 [重复]
【发布时间】:2014-04-11 04:25:31
【问题描述】:

我有下表:

perid   date    rating
10001   2005    RD
10001   2006    GN
10001   2007    GD
10002   2008    GD
10002   2009    YW
10002   2010    GN
10002   2011    GN
10003   2005    GD
10003   2006    GN
10003   2007    YW

我怎样才能把这个表格变成以下格式:

perid    2005    2006    2007    2008    2009    2010    2011
10001    RD      GN      GN      N/A     N/A     N/A     N/A
10002    N/A     N/A     N/A     GD      YW      GN      GN
10003    GD      GN      YW      N/A     N/A     N/A     N/A

或者如果我可以在 R 中做到这一点?

谢谢, P

【问题讨论】:

    标签: mysql r reshape reshape2


    【解决方案1】:

    在基本 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>
    

    【讨论】:

    • 我收到一个错误Error in [.data.frame(data, , idvar) : undefined columns selecte`` :(
    • +1 - 我以为你必须在 dcast 之前 melt,但显然不是。
    • @user3114046,如果数据已经是长格式(melt就是这样做的),那么在使用dcast之前不需要再次melt
    • @ Ananda - reshape 工作,你是对的,我拼错了 persid,但是使用 dcast,我得到的结果是 10 而不是 GN, @ 987654349@.
    • @AnandaMahto,同样是reshape,结果与 1 列不匹配,即 col rating.2005 具有所有 persid,col rating.2006 具有 rating.1005 的数据...不确定我做错了什么:(
    【解决方案2】:

    执行此操作的简单方法是使用 reshape2 包 -

    period <- c(10001,10001,10001,10002,10002,10002,10002,10003,10003,10003)  
    date  <- c(2005, 2006,2007,2008, 2009,2010,2011,2005,2006,2007)  
    rating <- c("RD","GN","GD","GD","YW","GN", "GN","GD", "GN","YW")
    a <- data.frame(period,date,rating)
    
    library(reshape2)
    b <- dcast(a,formula=period~date,value.var="rating")
    
    b
    >b
       period 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> 
    

    【讨论】:

    • ...这对我不存在的答案增加了什么?
    • 再次,dcast 给出了1s 和0s 的结果,而不是实际评分:(
    • perri Ma - 即使您使用 value.var 选项? @AnandaMahto - 使用的公式略有不同?我似乎得到了输出
    • @RHelp,嗯。我得到了和你一样的输出,我看到的唯一区别是你命名了“公式”参数。这只是一个重复的答案。
    猜你喜欢
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2017-04-05
    相关资源
    最近更新 更多