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

R:从另一个数据帧中查找最接近的较小值/日期,r,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

我有两个数据帧:

评级:

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
我想在数据框“Output”中添加一列,称为“Rating”。本栏来自数据框“评级”,并根据CUSIP和相应日期有效的评级获取评级

结果应如下所示:

输出_II(要生成的列额定值):

我已经试过dplyr和zoo了。它看起来像这样:

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

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

您可以完全加入数据帧,在CUSIP和Date上进行安排,并使用zoo中的na.locf()函数将最后一次评级观察向前推进,以填充NAs。由于您已安排了CUSIP和日期,因此缺失的评级将由适当的评级观察结果替换。最后,您需要过滤结果数据帧,使其仅包含原始输出数据帧中的行。最后一步的安全方法是与原始输出进行右连接,这也确保输出的排列顺序与原始顺序相同

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
数据:
评级在数据中,日期列是
date
POSIXct
类并不明显。它当前是一个
字符
列吗?没错。它实际上是一个日期(格式)。例如,“2009-01-30”merge.xts应该可以很好地解决这些问题,但我只花了15分钟的时间整理头发(我在两天前参加了数据营课程:()。它似乎只能通过索引连接,因此您必须先拆分两个表,然后转换为xts,然后连接,然后重新组装表,然后再重新转换为数据。如果您希望此布局的日期未排序,则不太美观…我将推荐一个好的xts解决方案。很好的方法,在完全连接上使用
zoo::na.locf
。+1您真的应该添加一组人,这是不安全的,因为现在是这样。我的意思是,如果你在
arrange
调用之后查看你的输出,你“幸运”的是,你有一个来自第一个df的值作为每个组的第一个评级值,否则你的
na.locf
会走得太远,填充应该保持为NAs的值(仍然是向上投票:)。我同意这一点,当然,你是对的,group_by()函数可以解决这个潜在的危险或者像我在上面的评论中建议的那样,在一个链中执行:
Output%%groupby(Date,CUSIP)%%>%slice(1)%%>%full\u join(Ratings)%%>%arrange(CUSIP,Date)%%>%groupby(CUSIP)%%>%mutate(Rating=na.locf(Rating,na.rm=F))%%>%right\u 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")
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