R dplyr select 两个独立事件之间的最小日期差行
R dplyr select row of minimum date difference between two separate events
我正在处理一个包含大约 400 个不同主题的数据集。对于这个例子,我只会使用两个。您可以使用此代码生成示例数据:
set.seed(100)
library(tidyr)
library(dplyr)
Subject<-c("A","A","A","A","A","A","B","B","B","B")
Event1<-c("01/01/2001","01/01/2001","01/01/2001","01/01/2001","09/09/2001","09/09/2001","09/09/2009","09/09/2009","09/09/2009","09/09/2009")
random.dates<-function(N,sd="2001-01-01",ed="2010-01-01"){
sd<-as.Date(sd,"%Y-%m-%d")
ed<-as.Date(ed,"%Y-%m-%d")
dt<-as.numeric(difftime(ed,sd))
ev<-sort(runif(N,0,dt))
rt<-sd+ev
}
Event1<-as.Date(Event1,"%m/%d/%Y")
Event1
Event2<-print(random.dates(10))
df<-data.frame(Subject,Event1,Event2)
df
并产生接近于此输出的输出:
Subject Event1 Event2
1 A 2001-01-01 2001-05-04
2 A 2001-01-01 2001-09-24
3 A 2001-01-01 2002-10-22
4 A 2001-01-01 2003-02-25
5 A 2001-09-09 2007-07-16
6 A 2001-09-09 2008-04-06
7 B 2009-09-09 2008-07-12
8 B 2009-09-09 2008-07-24
9 B 2009-09-09 2009-04-01
10 B 2009-09-09 2009-09-11
在这种情况下,我感兴趣的是首先将独特的主题与独特的 Event1 分组,我可以轻松做到这一点。从那里我需要 select 最接近 Event1 的 Event2 以获取那个独特的 Subject-Event1 组合,我真的需要帮助。对于此示例,这些数据应分解为 3 个不同的记录:
Subject Event1 Event2
1 A 2001-01-01 2001-05-04
2 A 2001-09-09 2008-04-06
3 B 2009-09-09 2009-09-11
我偷工减料了一个解决方案来生成 Subject-Event1 组合的 3 条记录:
df2<-df
df2$SubEv<-paste(df2$Subject,df2$Event1)
df2$Event1<-NULL
df2$Subject<-NULL
df2$Event2<-NULL
df2<-unique(df2)
df2<-separate(df2,SubEv,c("Subject","Event1"),sep=" ")
从这里我只是迷失了如何使 R select 从 df 到最接近事件 1 的事件 2 的日期。
我已经知道我的代码非常低效和草率(可能是因为我一开始就采用了这种方法)。我想知道如何做到这一点(老实说),如果有一种方法可以调用少于 10 行的代码,那就太棒了。
使用 dplyr:
library(dplyr)
df %>%
group_by(Subject, Event1) %>%
slice(which.min(abs(Event1 - Event2)))
# Subject Event1 Event2
# (chr) (date) (date)
# 1 A 2001-01-01 2001-07-05
# 2 A 2001-09-09 2004-05-02
# 3 B 2009-09-09 2008-04-24
评论:
group_by
可以处理多列。
slice
选择组内的行号。或者...
... %>% filter( row_number() == which.min(abs(Event1 - Event2)) )
对于平局,which.min
将 return 第一个 min
。有关详细信息,请参阅 ?which.min
。
数据: 当我 运行 OP 的代码时,我得到 df
看起来像
Subject Event1 Event2
1 A 2001-01-01 2001-07-05
2 A 2001-01-01 2002-07-14
3 A 2001-01-01 2003-04-27
4 A 2001-01-01 2003-10-09
5 A 2001-09-09 2004-05-02
6 A 2001-09-09 2005-03-21
7 B 2009-09-09 2005-05-10
8 B 2009-09-09 2005-12-02
9 B 2009-09-09 2005-12-21
10 B 2009-09-09 2008-04-24
这解释了为什么我的结果与 OP 的预期结果不完全匹配。
我正在处理一个包含大约 400 个不同主题的数据集。对于这个例子,我只会使用两个。您可以使用此代码生成示例数据:
set.seed(100)
library(tidyr)
library(dplyr)
Subject<-c("A","A","A","A","A","A","B","B","B","B")
Event1<-c("01/01/2001","01/01/2001","01/01/2001","01/01/2001","09/09/2001","09/09/2001","09/09/2009","09/09/2009","09/09/2009","09/09/2009")
random.dates<-function(N,sd="2001-01-01",ed="2010-01-01"){
sd<-as.Date(sd,"%Y-%m-%d")
ed<-as.Date(ed,"%Y-%m-%d")
dt<-as.numeric(difftime(ed,sd))
ev<-sort(runif(N,0,dt))
rt<-sd+ev
}
Event1<-as.Date(Event1,"%m/%d/%Y")
Event1
Event2<-print(random.dates(10))
df<-data.frame(Subject,Event1,Event2)
df
并产生接近于此输出的输出:
Subject Event1 Event2
1 A 2001-01-01 2001-05-04
2 A 2001-01-01 2001-09-24
3 A 2001-01-01 2002-10-22
4 A 2001-01-01 2003-02-25
5 A 2001-09-09 2007-07-16
6 A 2001-09-09 2008-04-06
7 B 2009-09-09 2008-07-12
8 B 2009-09-09 2008-07-24
9 B 2009-09-09 2009-04-01
10 B 2009-09-09 2009-09-11
在这种情况下,我感兴趣的是首先将独特的主题与独特的 Event1 分组,我可以轻松做到这一点。从那里我需要 select 最接近 Event1 的 Event2 以获取那个独特的 Subject-Event1 组合,我真的需要帮助。对于此示例,这些数据应分解为 3 个不同的记录:
Subject Event1 Event2
1 A 2001-01-01 2001-05-04
2 A 2001-09-09 2008-04-06
3 B 2009-09-09 2009-09-11
我偷工减料了一个解决方案来生成 Subject-Event1 组合的 3 条记录:
df2<-df
df2$SubEv<-paste(df2$Subject,df2$Event1)
df2$Event1<-NULL
df2$Subject<-NULL
df2$Event2<-NULL
df2<-unique(df2)
df2<-separate(df2,SubEv,c("Subject","Event1"),sep=" ")
从这里我只是迷失了如何使 R select 从 df 到最接近事件 1 的事件 2 的日期。
我已经知道我的代码非常低效和草率(可能是因为我一开始就采用了这种方法)。我想知道如何做到这一点(老实说),如果有一种方法可以调用少于 10 行的代码,那就太棒了。
使用 dplyr:
library(dplyr)
df %>%
group_by(Subject, Event1) %>%
slice(which.min(abs(Event1 - Event2)))
# Subject Event1 Event2
# (chr) (date) (date)
# 1 A 2001-01-01 2001-07-05
# 2 A 2001-09-09 2004-05-02
# 3 B 2009-09-09 2008-04-24
评论:
group_by
可以处理多列。
slice
选择组内的行号。或者...
... %>% filter( row_number() == which.min(abs(Event1 - Event2)) )
对于平局,which.min
将 return 第一个 min
。有关详细信息,请参阅 ?which.min
。
数据: 当我 运行 OP 的代码时,我得到 df
看起来像
Subject Event1 Event2
1 A 2001-01-01 2001-07-05
2 A 2001-01-01 2002-07-14
3 A 2001-01-01 2003-04-27
4 A 2001-01-01 2003-10-09
5 A 2001-09-09 2004-05-02
6 A 2001-09-09 2005-03-21
7 B 2009-09-09 2005-05-10
8 B 2009-09-09 2005-12-02
9 B 2009-09-09 2005-12-21
10 B 2009-09-09 2008-04-24
这解释了为什么我的结果与 OP 的预期结果不完全匹配。