R:从另一个数据框中找到最接近的较小值/日期

时间:2018-06-26 14:30:52

标签: r

我有两个数据框:

评分:

CUSIP   Date       Rating
BAEU    01.01.2014  A+
BAEU    30.01.2015  A
BAEU    28.02.2017  BB
BAEU    28.03.2018  BB
CUOD    01.03.2010  BBB
CUOD    02.03.2012  BB
CUOD    03.03.2016  AA
CUOD    04.03.2018  C
BBAE    20.06.2009  A
BBAE    21.06.2012  A+
BBAE    22.11.2015  B-
BBAE    23.06.2016  BBB

输出:

Date        CUSIP
01.05.2014  BAEU
01.01.2015  BAEU
01.02.2015  BAEU
01.01.2017  BAEU
02.01.2017  BAEU
15.03.2018  BAEU
01.05.2010  CUOD
02.08.2012  CUOD
01.01.2016  CUOD
04.05.2018  CUOD
20.06.2010  BBAE
21.01.2012  BBAE
23.11.2015  BBAE
01.01.2016  BBAE
23.06.2016  BBAE

我想在数据框“输出”中添加一列,称为“评分”。此列来自数据框“评分”,并基于CUSIP和在相应日期有效的评分进行评分。

结果应如下所示:

Output_II(要生成的列等级):

Date        CUSIP   Rating (to be generated, based on data frame Rating)
01.05.2014  BAEU    A+
01.01.2015  BAEU    A+
01.02.2015  BAEU    A
01.01.2017  BAEU    A
02.01.2017  BAEU    A
15.03.2018  BAEU    BB
01.05.2010  CUOD    BBB
02.08.2012  CUOD    BB
01.01.2016  CUOD    BB
04.05.2018  CUOD    C
20.06.2010  BBAE    A
21.01.2012  BBAE    A
23.11.2015  BBAE    B-
01.01.2016  BBAE    B-
23.06.2016  BBAE    BBB

我已经尝试过dplyr和Zoo。看起来像这样:

library(dplyr)
library(zoo)
Output_II = Output %>% 
  group_by(cusip, date) %>% 
  mutate(...)

但是,我没有找到完成代码的方法。

1 个答案:

答案 0 :(得分:2)

您可以完全加入数据框,安排CUSIP和日期,并使用zoo中的na.locf()函数向前进行最后的Rating观察以填充NA。由于您已经安排了CUSIP和日期,因此缺少的“评分”将由相应的“评分”观察结果代替。最后,您需要过滤结果数据框,使其仅包含来自原始输出数据框的行。最后一步的安全方法是与原始Output进行right_join,这还可以确保Output的排列顺序与原始顺序相同。

library(dplyr)
library(zoo)

Output %>% 
  full_join(Ratings) %>% 
  arrange(CUSIP, Date) %>% 
  mutate(Rating = na.locf(Rating)) %>% 
  right_join(Output)

         Date CUSIP Rating
1  2014-05-01  BAEU     A+
2  2015-01-01  BAEU     A+
3  2015-02-01  BAEU      A
4  2017-01-01  BAEU      A
5  2017-01-02  BAEU      A
6  2018-03-15  BAEU     BB
7  2010-05-01  CUOD    BBB
8  2012-08-02  CUOD     BB
9  2016-01-01  CUOD     BB
10 2018-05-04  CUOD      C
11 2010-06-20  BBAE      A
12 2012-01-21  BBAE      A
13 2015-11-23  BBAE     B-
14 2016-01-01  BBAE     B-
15 2016-06-23  BBAE    BBB

数据:

Ratings <- read.table(text = "CUSIP   Date       Rating
                      BAEU    01.01.2014  A+
                        BAEU    30.01.2015  A
                      BAEU    28.02.2017  BB
                      BAEU    28.03.2018  BB
                      CUOD    01.03.2010  BBB
                      CUOD    02.03.2012  BB
                      CUOD    03.03.2016  AA
                      CUOD    04.03.2018  C
                      BBAE    20.06.2009  A
                      BBAE    21.06.2012  A+
                        BBAE    22.11.2015  B-
                        BBAE    23.06.2016  BBB", h = T )

Output <- read.table(text = "Date        CUSIP
01.05.2014  BAEU
                     01.01.2015  BAEU
                     01.02.2015  BAEU
                     01.01.2017  BAEU
                     02.01.2017  BAEU
                     15.03.2018  BAEU
                     01.05.2010  CUOD
                     02.08.2012  CUOD
                     01.01.2016  CUOD
                     04.05.2018  CUOD
                     20.06.2010  BBAE
                     21.01.2012  BBAE
                     23.11.2015  BBAE
                     01.01.2016  BBAE
                     23.06.2016  BBAE", h = T)

Ratings$Date <- as.Date(Ratings$Date, "%d.%m.%Y")
Output$Date <- as.Date(Output$Date, "%d.%m.%Y")

基于注释,如果并非输出中的所有CUSIPS都具有输出中第一个CUSIP日期之前的“等级”,则以下代码可能更安全。另外,我使用的数据也经过了稍微修改以显示会发生什么:

Ratings <- read.table(text = "CUSIP   Date       Rating
                      BAEU    01.01.2014  A+
                        BAEU    30.01.2015  A
                      BAEU    28.02.2017  BB
                      BAEU    28.03.2018  BB
                      CUOD    01.03.2010  BBB
                      CUOD    02.03.2012  BB
                      CUOD    03.03.2016  AA
                      CUOD    04.03.2018  C
                      BBAE    20.06.2009  A
                      BBAE    21.06.2012  A+
                        BBAE    22.11.2015  B-
                        BBAE    23.06.2016  BBB
                      TEST 01.01.2018 AAA", h = T )

Output <- read.table(text = "Date        CUSIP
01.05.2014  BAEU
                     01.01.2015  BAEU
                     01.02.2015  BAEU
                     01.01.2017  BAEU
                     02.01.2017  BAEU
                     15.03.2018  BAEU
                     01.05.2010  CUOD
                     02.08.2012  CUOD
                     01.01.2016  CUOD
                     04.05.2018  CUOD
                     20.06.2010  BBAE
                     21.01.2012  BBAE
                     23.11.2015  BBAE
                     01.01.2016  BBAE
                     23.06.2016  BBAE
                     01.01.2017 TEST
                     01.01.2019 TEST", h = T)

Ratings$Date <- as.Date(Ratings$Date, "%d.%m.%Y")
Output$Date <- as.Date(Output$Date, "%d.%m.%Y")
library(dplyr)
library(zoo)


Output %>% 
  full_join(Ratings) %>% 
  arrange(CUSIP, Date) %>% 
  group_by(CUSIP) %>% 
  mutate(Rating = na.locf(Rating, na.rm = F)) %>% 
  right_join(Output)


         Date  CUSIP Rating
       <date> <fctr> <fctr>
 1 2014-05-01   BAEU     A+
 2 2015-01-01   BAEU     A+
 3 2015-02-01   BAEU      A
 4 2017-01-01   BAEU      A
 5 2017-01-02   BAEU      A
 6 2018-03-15   BAEU     BB
 7 2010-05-01   CUOD    BBB
 8 2012-08-02   CUOD     BB
 9 2016-01-01   CUOD     BB
10 2018-05-04   CUOD      C
11 2010-06-20   BBAE      A
12 2012-01-21   BBAE      A
13 2015-11-23   BBAE     B-
14 2016-01-01   BBAE     B-
15 2016-06-23   BBAE    BBB
16 2017-01-01   TEST   <NA>
17 2019-01-01   TEST    AAA