How to create a pivot table in R with multiple (3+) variables

前端 未结 5 1175
灰色年华
灰色年华 2020-12-06 07:09

I am having problems in create a pivot table with a data frame like this:

c1   c2          c3         c4
E   5.76         201    A la vista
E   47530.71              


        
5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-06 07:48

    Here are a few more options, two in base R and one using the more recent "dplyr" and "tidyr" packages.

    Base R's reshape can't handle aggregation, so you need to resort to other functions (for example, aggregate) before you can do the reshaping.

    reshape(
      aggregate(c2 ~ c1 + c3 + c4, mydata, sum), 
      direction = "wide", idvar = c("c1", "c3"), timevar = "c4")
    #      c1  c3 c2.A la vista c2.Montoxv_a186d c2.Montoxv_a60d c2.Montoxv_a90d
    # 1     E 201      47619.32               NA              NA              NA
    # 2     L 201      11376.55               NA              NA              NA
    # 3     E 203      73412.28               NA              NA              NA
    # 4     E 124            NA         667812.8              NA              NA
    # 5     L 124            NA         471730.2              NA        81146.25
    # 6     E 202            NA               NA        116443.6              NA
    

    If your aggregation only involves sum, you can also use xtabs to do the aggregation. Since you have multiple values on the RHS of the formula, you'll end up with a multi-dimensional array, but that can easily be coerced into a rectangular form by using ftable (as was done by @BondedDust in his answer). Note that the output using ftable is a little different from others in that it returns all combinations of grouping variables by default, even where there would otherwise be fully empty rows.

    ftable(xtabs(c2 ~ c1 + c3 + c4, mydata))
    #           c4 A la vista Montoxv_a186d Montoxv_a60d Montoxv_a90d
    # c1    c3                                                       
    #     E 124          0.00     667812.84         0.00         0.00
    #       201      47619.32          0.00         0.00         0.00
    #       202          0.00          0.00    116443.56         0.00
    #       203      73412.28          0.00         0.00         0.00
    #     L 124          0.00     471730.20         0.00     81146.25
    #       201      11376.55          0.00         0.00         0.00
    #       202          0.00          0.00         0.00         0.00
    #       203          0.00          0.00         0.00         0.00
    

    Finally, you can also use the functions in "tidyr" and "dplyr" which offer similar functionality to the tools in "reshape" and "reshape2", but with a slightly different "grammar".

    library(tidyr)
    library(dplyr)
    mydata %>%                     ## The source dataset
      group_by(c1, c3, c4) %>%     ## Grouping variables
      summarise(c2 = sum(c2)) %>%  ## aggregation of the c2 column
      ungroup() %>%                ## spread doesn't seem to like groups
      spread(c4, c2)               ## spread makes the data wide
    # Source: local data frame [6 x 6]
    # 
    #      c1  c3 A la vista Montoxv_a186d Montoxv_a60d Montoxv_a90d
    # 1     E 124         NA      667812.8           NA           NA
    # 2     E 201   47619.32            NA           NA           NA
    # 3     E 202         NA            NA     116443.6           NA
    # 4     E 203   73412.28            NA           NA           NA
    # 5     L 124         NA      471730.2           NA     81146.25
    # 6     L 201   11376.55            NA           NA           NA
    

提交回复
热议问题