如何更改分组数据的顺序

时间:2017-12-28 16:52:05

标签: r dplyr panel

下面的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

按&#34; id&#34;对数据进行分组并计算每组的平均值

 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

请注意,在原始数据中,组的顺序是第一个&#34; A&#34;,第二个&#34; B&#34;第三个&#34; C&#34;等等。但是,按降序排列的组平均值显示&#34; D&#34;具有最大价值,那么&#34; C&#34;有第二大,然后是&#34; B&#34;最后&#34; A&#34;走到最后。这是我希望放置原始数据的顺序,结果如下所示。

 > 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新手的回答有点简单,我将非常感激。

5 个答案:

答案 0 :(得分:2)

如果您希望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)

答案 1 :(得分:0)

可能的解决方案是:

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)

答案 2 :(得分:0)

这是一个潜在的基础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

答案 3 :(得分:0)

如果我理解你的问题:

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

否则,您能提供预期输出的示例吗?

答案 4 :(得分:0)

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

#include <string.h>
#include <stdio.h>

void fun(char *str, char *data, int start, int end, int idx, int depth)
{
    if (idx == depth)
    {
        for (int j = 0; j < depth; j++)
            printf("%c", data[j]);
        printf("\n");
        return;
    }
    for (int i = start; i <= end && end - i + 1 >= depth - idx; i++)
    {
        data[idx] = str[i];
        fun(str, data, i + 1, end, idx + 1, depth);
    }
}

int main()
{
    char *str = "ABCD";
    int i = 0;

    while (i < strlen(str))
    {
        char data[i + 1];
        fun(str, data, 0, strlen(str) - 1, 0, i + 1);
        i++;
    }
    return (0);
}

重新排序原始数据:

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