首页 > 解决方案 > 根据组内日期比较组合数据集

问题描述

我有两个数据集,“Df_A”和“Df_B”:

Df_A 
     Date     Info A   Info B
9/19/18 23:00     36       48
9/18/18 23:00     47       30
9/17/18 23:00     51       3
8/14/18 23:00     45       16
8/6/18 23:00      37       13
8/5/18 23:00      42       66
7/11/18 23:00     42       53
7/4/18 23:00      38       10

Df_B
Released Info   Event     Value X
9/6/2018 22:30  Event A   51.8
8/6/2018 22:30  Event A   52
7/5/2018 22:30  Event A   50.6
6/6/2018 22:30  Event A   54
9/2/2018 22:30  Event C   48
7/31/2018 22:30 Event C   45
9/4/2018 22:30  Event D   58.7
8/2/2018 22:30  Event D   56.2
7/3/2018 22:30  Event D   57.3
6/4/2018 22:30  Event D   51.1
5/2/2018 22:30  Event D   54.2
4/4/2018 22:30  Event D   59.8
9/3/2018 1:30   Event E   61.8
8/6/2018 1:30   Event E   63
7/2/2018 1:30   Event E   65.2

“日期”和“Released.info”都是因素。

我有一个向量“事件”,其中包含我需要解析的“Df_B”中的事件,例如

Events <- c("Event A", "Event D")

对于“Df_B”中的每个“事件”,我想检查“Df_A”中的“日期”是否大于“Df_B”中的“发布信息”。如果是这样,我想将'Event A'和'Event B'的相应值添加到'Df_A'。

所需的输出:

Date           Info A   Info B  Event A Event D
9/19/18 23:00   36       48       51.8   58.7
9/18/18 23:00   47       30       51.8   58.7
9/17/18 23:00   51       3        51.8   58.7
8/14/18 23:00   45       16       52     56.2
8/6/18 23:00    37       13       52     56.2
8/5/18 23:00    42       66       50.6   56.2
7/11/18 23:00   42       53       50.6   57.3
7/4/18 23:00    38       10       54     57.3

例如,对于9/19/18 23:009/18/18 23:00并且9/17/18 23:00在 'Df_A' 中,组 'Event A' 在 'Df_B' 中最接近的先前日期是9/6/2018 22:30。因此,对于这些行,我们从“Df_B”中选择值 51.8。对于 中的所有日期Df_A,以及“Df_B”中的“事件 A”和“事件 B”,依此类推。

我想在“Df_A”中添加新的 n 列,在本例中为“事件 A”和“事件 D”,但可能更多。

为此,我一直在尝试为动态事件数量创建一些动态变量,如下所示(因为事件来自 csv 作为矩阵):

#To Create a variable for each Event
ListEvents <- as.list(as.vector(Events))
names(ListEvents) <- paste("Variable", 1:length(ListEvents), sep = "")
list2env(ListEvents,envir = .GlobalEnv)

在为每个事件创建一个变量之后,我正在考虑创建一个循环,这样我就可以为每个事件创建一个子集,然后将日期(Df_A)与发布日期(Df_B)进行比较,并将其作为列添加到 Df_A 中。但我知道这是一种不必要的复杂和低效的方法。有人可以帮助我吗?

标签: rdatetime

解决方案


以下重现了您的预期输出:

events <- c("Event A", "Event D")
library(tidyverse)
library(lubridate)
map(events, ~Df_A %>%
    mutate(Event := .x) %>%
    left_join(Df_B) %>%
    mutate(
        Date = mdy_hm(Date),
        Released.Info = mdy_hm(Released.Info)) %>%
        group_by(Date) %>%
        mutate(diff = difftime(Released.Info, Date, units = "days")) %>%
        filter(diff < 0) %>%
        filter(diff == max(diff)) %>%
        select(-Released.Info, -diff) %>%
        spread(Event, Value.X)) %>%
    reduce(left_join) %>%
    arrange(desc(Date))
## A tibble: 8 x 5
## Groups:   Date [8]
#  Date                Info.A Info.B `Event A` `Event D`
#  <dttm>               <int>  <int>     <dbl>     <dbl>
#1 2018-09-19 23:00:00     36     48      51.8      58.7
#2 2018-09-18 23:00:00     47     30      51.8      58.7
#3 2018-09-17 23:00:00     51      3      51.8      58.7
#4 2018-08-14 23:00:00     45     16      52        56.2
#5 2018-08-06 23:00:00     37     13      52        56.2
#6 2018-08-05 23:00:00     42     66      50.6      56.2
#7 2018-07-11 23:00:00     42     53      50.6      57.3
#8 2018-07-04 23:00:00     38     10      54        57.3

这个想法是添加一Events列,Df_A其中包含向量中给出的条目events;然后我们对 and 进行左连接Df_A,并仅选择与andDf_B之间负时间差最短的行(即and部分)。剩下的就是重塑和重新安排以重现您的预期输出。Released.InfoDatefilter(diff < 0)filter(diff == max(diff))


样本数据

Df_A <-read.table(text =
    "     Date        'Info A'  'Info B'
'9/19/18  23:00'    36       48
'9/18/18  23:00'    47       30
'9/17/18  23:00'    51       3
'8/14/18  23:00'    45       16
'8/6/18   23:00'    37       13
'8/5/18   23:00'    42       66
'7/11/18  23:00'    42       53
'7/4/18   23:00'    38       10", header = T)

Df_B <- read.table(text  =
    "'Released Info'   Event     'Value X'
'9/6/2018 22:30'  'Event A'   51.8
'8/6/2018 22:30'  'Event A'   52
'7/5/2018 22:30'  'Event A'   50.6
'6/6/2018 22:30'  'Event A'   54
'9/2/2018 22:30'  'Event C'   48
'7/31/2018 22:30' 'Event C'   45
'9/4/2018 22:30'  'Event D'   58.7
'8/2/2018 22:30'  'Event D'   56.2
'7/3/2018 22:30'  'Event D'   57.3
'6/4/2018 22:30'  'Event D'   51.1
'5/2/2018 22:30'  'Event D'   54.2
'4/4/2018 22:30'  'Event D'   59.8
'9/3/2018 1:30'   'Event E'   61.8
'8/6/2018 1:30'   'Event E'   63
'7/2/2018 1:30'   'Event E'   65.2", header = T)

推荐阅读