【问题标题】:How to change order of a grouped data如何更改分组数据的顺序
【发布时间】:2017-12-28 16:52:05
【问题描述】:

下面的 df 与我的原始数据具有相似的结构。我在这里要完成的是按“id”对数据进行分组,取这些组的平均利润,然后根据它们的平均值对组进行重新排序。

>mydata <- structure(list(id = c("A", "A", "A", "A", "B", "B", "B", "B", 
"C", "C", "C", "D", "D"), year = c(2000L, 2001L, 2002L, 2003L, 
2000L, 2001L, 2002L, 2003L, 2000L, 2002L, 2003L, 2000L, 2001L
), sales = c(2000L, 2050L, 2100L, 2150L, 2200L, 2250L, 2300L, 
2350L, 2400L, 2500L, 2550L, 2600L, 2650L), profit = c(200L, 245L, 
290L, 335L, 380L, 425L, 470L, 515L, 560L, 650L, 695L, 740L, 785L
)), .Names = c("id", "year", "sales", "profit"), row.names = c(NA, 
13L), class = c("data.table", "data.frame"))
> mydata
   id year sales profit
1   A 2000  2000    200
2   A 2001  2050    245
3   A 2002  2100    290
4   A 2003  2150    335
5   B 2000  2200    380
6   B 2001  2250    425
7   B 2002  2300    470
8   B 2003  2350    515
9   C 2000  2400    560
10  C 2002  2500    650
11  C 2003  2550    695
12  D 2000  2600    740
13  D 2001  2650    785

按“id”对数据进行分组并计算每组的平均值

 group_mean=mydata%>%group_by(id)%>%summarise(m=mean(profit))%>%arrange(desc(m))
> group_mean
# A tibble: 4 x 2
     id     m
  <chr> <dbl>
1     D 762.5
2     C 635.0
3     B 447.5
4     A 267.5

请注意,在原始数据中,组的顺序是第一个“A”,第二个“B”,第三个“C”,依此类推。但是按降序排列的组平均值显示“D”具有最大值,然后“C”具有第二大值,然后是“B”,最后是“A”。这是我希望放置原始数据的顺序,结果 df 如下所示。

 > newdata
   id year sales profit
1   D 2000  2600    740
2   D 2001  2650    785
3   C 2000  2400    560
4   C 2002  2500    650
5   C 2003  2550    695
6   B 2000  2200    380
7   B 2001  2250    425
8   B 2002  2300    470
9   B 2003  2350    515
10  A 2000  2000    200
11  A 2001  2050    245
12  A 2002  2100    290
13  A 2003  2150    335

你看,组内的顺序保持不变,需要改变的是组的顺序。另一个问题,我怎样才能根据 2000 年的销售数字完成类似的分组重新排序。 感谢您的时间和提前回答,如果我是 R 新手,如果答案能简单一点,我将不胜感激。

【问题讨论】:

    标签: r dplyr panel


    【解决方案1】:

    如果您希望id 具有特定顺序,请将其转换为级别按该顺序排列的因素。 reorder 函数对此非常方便。然后按id 列排序将产生您想要的顺序。

    对于您的情况:

    mydata %>%
      mutate(id = factor(id),
             id = reorder(id, -profit, FUN = mean)) %>%
      arrange(id)
    #    id year sales profit
    # 1   D 2000  2600    740
    # 2   D 2001  2650    785
    # 3   C 2000  2400    560
    # 4   C 2002  2500    650
    # 5   C 2003  2550    695
    # 6   B 2000  2200    380
    # 7   B 2001  2250    425
    # 8   B 2002  2300    470
    # 9   B 2003  2350    515
    # 10  A 2000  2000    200
    # 11  A 2001  2050    245
    # 12  A 2002  2100    290
    # 13  A 2003  2150    335
    

    将顺序实际编码到因子的级别中很好,因为它将是绘图的默认顺序。


    要获得基于 2000 年销售额的订单,我将获得该订单,然后明确应用它:

    ord_2000 = mydata %>% filter(year == 2000) %>% group_by(id) %>% 
      summarize(sales = mean(sales)) %>%
      arrange(-sales) %>% pull(id)
    
    mydata = mutate(mydata, id = factor(id, levels = ord_2000))
    

    或者,您仍然可以使用 reorder,但首先按年份对数据进行排序,以便 2000 排在第一位,然后不要使用 mean 进行重新排序功能,而是使用 head 并拉出最高记录:

    mydata %>% arrange(year) %>%
      mutate(id = factor(id),
             reorder(id, -sales, FUN = head, 1)) %>%
      arrange(id)
    

    【讨论】:

    • 像魅力一样工作谢谢!如何根据 2000 年的销售数量进行类似的重新排序?
    • 能否请您为“ord_2000”部分提供另一行代码,它似乎没有提供我需要的内容。
    • 确保您的dplyr 是最新的。 pull 是一个相对较新的添加。我提供的行在您的测试数据上运行良好。
    • 也许我不够清楚我需要什么。无需计算平均销售额,我需要仅基于 2000 的销售数量的团体订单。在这种情况下,“id”的排序类似于 c(“D”,“D”,“C”,“C”,“C”,“B”,“B”,“B”,“B”, A","A","A","A" 从 2000 年最大的销售额到最小的
    • 无论有无均值,代码都可以正常工作,但如果您愿意,可以随意删除 group_bysummarize() 调用。将其保留下来,无论您在 2000 年是否有一个或多个观察值(每个 id),代码都可以正常工作。如果您每个 id 有超过一年的 2000 点,则将其取出将意味着代码将不起作用。我不想对您的数据做出假设。我将按原样保留我的答案,因为它更笼统。
    【解决方案2】:

    可能的解决方案是:

    group_mean=mydata%>%group_by(id)%>%
                        summarise(m=mean(profit))%>%
                        arrange(desc(m)) %>% as.data.frame()   
    
    
    mydata %>% mutate(id=factor(id,levels = group_mean$id)) %>%
               arrange(id)
    

    【讨论】:

      【解决方案3】:

      这是一个潜在的基础 R 解决方案

      specific_order <- LETTERS[4:1]
      mydata[unlist(sapply(specific_order, function(i) which(i == mydata$id))), ]    
      
      # id year sales profit
      # 12  D 2000  2600    740
      # 13  D 2001  2650    785
      # 9   C 2000  2400    560
      # 10  C 2002  2500    650
      # 11  C 2003  2550    695
      # 5   B 2000  2200    380
      # 6   B 2001  2250    425
      # 7   B 2002  2300    470
      # 8   B 2003  2350    515
      # 1   A 2000  2000    200
      # 2   A 2001  2050    245
      # 3   A 2002  2100    290
      # 4   A 2003  2150    335
      

      【讨论】:

        【解决方案4】:

        如果我理解你的问题:

        # If you want to sort in different way
        arrange(mydata,desc(id),desc(sales))
        # If you want to keep year == 2000 and sort your data : 
        arrange(mydata[mydata$year == 2000,],desc(id),desc(sales))
        

        否则,你能提供一个预期输出的例子吗?

        【讨论】:

        • 我似乎无法正确发布 df 结构,它显示为普通文本
        • newest # A tibble: 16 x 3 id year sales 1 A 2000 163.40165 2 A 2001 112.59313 3 A 2002 91.59946 4 A 2003 131.95467 5 B 2000 2001 111.17791 7 B 2002 165.67058 9 C 2001 73.85365 11 C 2002 203.85365 11 C 2002 203.94043 12 C 2003 79.0435 13 D 2001 119.47931 15 D 2002 45.00866 16 D 2003 87.11828 SPAN>
        • 我会尝试口头解释。当您像 >newest_data%>% filter(year==2000)%>%arrange (sales) 进行过滤时,结果是这个表 A tibble: 4 x 3 id year sales 1 D 2000 25.65043 2 B 2000 74.47537 3 C 2000 101.53864 4 A 2000 163.40165 “D”排在第一位,因为它在 2000 年的销售额最大,同样,“A”排在最后,因为它的销售额较小。现在,我需要对 df 进行重新排序,以便按照 2000 销售编号排序,“D”先行,然后是“B”,然后是“C”,最后是“A”
        【解决方案5】:

        要按组排序平均值,请将变量从“m”更改为“id”

        mydata %>%
          as_tibble() %>%
          group_by(id) %>%
          summarize(m = mean(profit)) %>%
          arrange(id) 
        

        重新排序您的原始数据:

        mydata %>%
          arrange(desc(id))
        

        【讨论】:

        • 这在代码中起作用 bc "as_tibble()。bc 我尝试在分组数据后重新排序,但每次都失败。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-05
        • 2012-05-27
        • 1970-01-01
        • 2016-06-19
        • 1970-01-01
        • 2022-01-14
        相关资源
        最近更新 更多