r - 根据组内日期比较组合数据集
问题描述
我有两个数据集,“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:00
,9/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 中。但我知道这是一种不必要的复杂和低效的方法。有人可以帮助我吗?
解决方案
以下重现了您的预期输出:
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.Info
Date
filter(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)