关于排序:在子组内的R数据框中对数据进行排序

Sort data in R data frame within subgroups

本问题已经有最佳答案,请猛点这里访问。

我有一个很大的Bond数据框架,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   ISIN      CF       DATE
1   A   105.750  2016-09-30
2   B   104.875  2016-05-31
3   C   106.875  2017-02-13
4   D   103.875  2016-10-07
5   E   5.000    2016-04-21
6   E   5.000    2017-04-21
7   E   5.000    2018-04-21
8   E   5.000    2019-04-21
9   E   105.000  2020-04-21
10  F   7.800    2016-09-09
11  F   7.800    2017-09-09
12  F   7.800    2018-09-09
13  F   7.800    2019-09-09
14  F   107.800  2020-09-09

我想按isin代码对元素进行分组,然后按递增的顺序对组中的日期进行排序(在上面的示例中已经完成了),然后我想对组(在本示例中,A、B、C、D、E、F)进行排序,以便具有最早日期的组首先出现,然后是具有第二个最早日期的组,依此类推。

我希望它看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  ISIN     CF      DATE
16  E   5.000   2016-04-21
15  E   5.000   2017-04-21
14  E   5.000   2018-04-21
13  E   5.000   2019-04-21
12  E   105.000 2020-04-21
 7  B   104.875 2016-05-31
10  F    7.800  2016-09-09
11  F    7.800  2017-09-09
12  F    7.800  2018-09-09
13  F    7.800  2019-09-09
14  F   107.800 2020-09-09
6   A   105.750 2016-09-30
23  D   103.875 2016-10-07
22  C   106.875 2017-02-13

我在这个问题上试过这样的方法:

How to sort a dataframe by column(s)?

1
df<-df[order(df$ISIN,df$DATE ),]

但它不能满足我的需要。

我不想

谢谢你的帮助!


1
2
library(dplyr)
sorted <- df %>% arrange(ISIN,DATE)


新更新

更好的是,现在有了ISIN和更多的领带,我使用了两个辅助柱。首先,我按日期生成订单,然后按isin分组,并获取每个组的最小值(这就给了我组订单)。我的data.frame名为b。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ord<-B %>% arrange(DATE) %>% mutate(ord=order(DATE))
ord2<-ord %>% group_by(ISIN) %>% summarize(min_ord=min(ord))
ord3<-merge(ord,ord2)
ord3<-ord3 %>% arrange(min_ord)

ISIN      CF       DATE ord min_ord
1     E   5.000 2016-04-21   1       1
2     E   5.000 2017-04-21   7       1
3     E   5.000 2018-04-21   9       1
4     E   5.000 2019-04-21  11       1
5     E 105.000 2020-04-21  13       1
6     B 104.875 2016-05-31   2       2
7     F   7.800 2017-09-09   8       3
8     F   7.800 2018-09-09  10       3
9     F   7.800 2019-09-09  12       3
10    F 107.800 2020-09-09  14       3
11    F   7.800 2016-09-09   3       3
12    A 105.750 2016-09-30   4       4
13    D 103.875 2016-10-07   5       5
14    C 106.875 2017-02-13   6       6

可以使用管道中的select(isin:date)删除多余的列。我保留它们是因为我认为它们可以方便地进行额外的计算。

旧更新

好吧,问题是你的ISIN值对你想要的订单不起作用。有时,您的ISI按"降序"顺序排列(例如,503326>255820>255817),但有时不按"降序"顺序排列,您希望您的日期列对您的data.frame进行排序(例如,2016-05-31在2016-09-30之前,2016-10-07在2017-02-13之前)。

因为在这种情况下,ISIN允许以伪方便的方式使用ifelse:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
df %>% mutate(ord=ifelse(ISIN=="XS0503326083",1,
                  ifelse(ISIN=="XS0255820804",2,
                  ifelse(ISIN=="XS0255817685",3,
                  ifelse(ISIN=="XS0438753294",4,5))))) %>%
       arrange(ord)

  row.names         ISIN      CF       DATE ord
1        16 XS0503326083   5.000 2016-04-21   1
2        15 XS0503326083   5.000 2017-04-21   1
3        14 XS0503326083   5.000 2018-04-21   1
4        13 XS0503326083   5.000 2019-04-21   1
5        12 XS0503326083 105.000 2020-04-21   1
6         7 XS0255820804 104.875 2016-05-31   2
7         6 XS0255817685 105.750 2016-09-30   3
8        23 XS0438753294 103.875 2016-10-07   4
9        22 XS0286431100 106.875 2017-02-13   5

我知道在这种情况下,您可能有许多ISIN值。此外,在您的示例中,唯一绑定的ISI值将按日期和CF排列,不会出现任何问题。这可能不适用于更大的数据帧。


使用data.table时:

1
DT <- data.table(yourDF, key = c("ISIN","Date"))