目标:将日期从一个数据框映射到另一个数据框,因为它处于特定日期间隔内。例如,假设我们需要在2017年12月20日至2017年12月25日或2017年12月26日至2017年12月30日的时间间隔内提供礼品,并收到礼品发件人的回复。 2017年12月23日。我想创建一个函数,可以根据它所在的日期间隔来确定响应日期的放置位置。在上面的示例中,响应日期将在2017年12月20日至2017年12月25日期间。 注意:下面的“匹配”一词表示从一个数据框到另一个数据框满足某个条件。
以下是一些示例代码,用于演示我的意思。
# Creating the Data Frame with a start and end date interval
StartDate <- seq(as.Date("2000/1/1"), by = "month", length.out = 10)
EndDate <- StartDate +7
Dates_Interval <- data.frame(StartDate,EndDate)
# Creating a second data frame with the response dates only
ResponseDate <- seq(as.Date("2000/1/6"), by = "month", length.out = 10)
Response_Substitute <- data.frame(ResponseDate)
# Substituting random NA values
Response_Substitute[c(1,5,8),] <- NA
# > Response_Substitute
# ResponseDate
# 1 <NA>
# 2 2000-02-09
# 3 2000-03-06
# 4 2000-04-06
# 5 <NA>
# 6 2000-06-06
# 7 2000-07-06
# 8 <NA>
# 9 2000-09-06
# 10 2000-10-06
# Creating a function which evaluates a value in data frame two
# (Response_Substitute) and checks
# whether it meets
# a condition in Dates_Interval.
dateresponses <- function(x,y,z) {
sub_date <- ifelse ( y <=x && x <= z, x, NA)
converteddate <- as.Date(sub_date, origin = "1899-12-30")
return(converteddate)
}
# Example of the function in use to show how it matches a certain condition.
x <- Response_Substitute[2,1]
b <- dateresponses(x,Dates_Interval[2,1],Dates_Interval[2,2])
# > b
# [1] "1930-02-04"
# Example of the function in use to show when a response date does not
# match a certain condition
x <- Response_Substitute[2,1] <- as.Date("2000/2/9")
b <- dateresponses(x,Dates_Interval[2,1],Dates_Interval[2,2])
# > b
# [1] NA
# Example of the function in use to show when there is no response date in
# the Response_Substitute variable
x <- Response_Substitute[1,1]
b <- dateresponses(x,Dates_Interval[2,1],Dates_Interval[2,2])
# > b
# [1] NA
我需要一个能够在Dates_Interval
数据框中创建新列的功能,该列与响应日期相匹配,其日期间隔来自StartDate
和EndDate
列。如果没有匹配,则如果没有响应,则响应将为NA
。如果有响应但,响应日期不会落入任何时间间隔,那么我希望创建一个能够捕获不匹配响应的数据帧。
这是最终数据框的样子:
Dates_Interval$ResponseDate <- Response_Substitute
# > Dates_Interval
# StartDate EndDate ResponseDate
# 1 2000-01-01 2000-01-08 <NA>
# 2 2000-02-01 2000-02-08 2000-02-06
# 3 2000-03-01 2000-03-08 2000-03-06
# 4 2000-04-01 2000-04-08 2000-04-06
# 5 2000-05-01 2000-05-08 <NA>
# 6 2000-06-01 2000-06-08 2000-06-06
# 7 2000-07-01 2000-07-08 2000-07-06
# 8 2000-08-01 2000-08-08 <NA>
# 9 2000-09-01 2000-09-08 2000-09-06
# 10 2000-10-01 2000-10-08 2000-10-06
对于不 NA
但不匹配任何时间间隔的响应日期,可以像这样创建另一个数据帧:
Unmatched_Response_Date <- data.frame(seq(as.Date("2000/1/9"), by = "month",
length.out = 2))
colnames(Unmatched_Response_Date) <- "Unmatched Responses"
Unmatched_Response_Date
# > Unmatched_Response_Date
# Unmatched Responses
# 1 2000-01-09
# 2 2000-02-09
修改:
使用dateresponses
函数时,我注意到了一些错误。当我使用Response_substitute
数据框中的日期时。日期的输出与数据框不同。例如对于Response_substitute[2,1]
,该值应为2000-02-09
,但我得1930-02-04
。还有什么想法可以解决这个问题吗?
答案 0 :(得分:0)
以下是您提供的代码:
StartDate <- seq(as.Date("2000/1/1"), by = "month", length.out = 10)
EndDate <- StartDate +7
Dates_Interval <- data.frame(StartDate,EndDate)
# Creating a second data frame with the response dates only
ResponseDate <- seq(as.Date("2000/1/6"), by = "month", length.out = 10)
Response_Substitute <- data.frame(ResponseDate)
# Substituting random NA values
Response_Substitute[c(1,5,8),] <- NA
所以为了回答你的问题,我添加了另一个日期列,以便我们在两个data.frames中都有一个间隔。我还从包含响应的第一个data.frame中删除了NA值。这些似乎与您的预期产量无关。纠正我,如果错了。
Response_Substitute$Date2 <- Response_Substitute$ResponseDate - 1
Response_Substitute <- Response_Substitute[!is.na(Response_Substitute$ResponseDate),]
这个问题的关键在于使用名为foverlaps()
的data.table函数。从文档中,这是一个快速重叠连接功能。它旨在找到两个间隔重叠的位置并将数据连接在一起。下面的代码就是这样。
这也是我需要在Response_Substitute
中生成另一个日期的原因。 foverlaps()
需要两个时间间隔才能正常工作。
library(data.table)
Dates_Interval <- as.data.table(Dates_Interval)
Response_Substitute <- as.data.table(Response_Substitute)
setkey(Response_Substitute, Date2, ResponseDate)
join_df <- foverlaps(Dates_Interval, Response_Substitute,
by.x = c('StartDate', 'EndDate'))
输出:
ResponseDate Date2 StartDate EndDate
1: <NA> <NA> 2000-01-01 2000-01-08
2: 2000-02-06 2000-02-05 2000-02-01 2000-02-08
3: 2000-03-06 2000-03-05 2000-03-01 2000-03-08
4: 2000-04-06 2000-04-05 2000-04-01 2000-04-08
5: <NA> <NA> 2000-05-01 2000-05-08
6: 2000-06-06 2000-06-05 2000-06-01 2000-06-08
7: 2000-07-06 2000-07-05 2000-07-01 2000-07-08
8: <NA> <NA> 2000-08-01 2000-08-08
9: 2000-09-06 2000-09-05 2000-09-01 2000-09-08
10: 2000-10-06 2000-10-05 2000-10-01 2000-10-08
最后一步是删除列,并生成不匹配的空向量。
# Removes the Date2 Column
join_df[, Date2:=NULL]
# Generate list of responses that didn't join
setdiff(Response_Substitute$ResponseDate, join_df$ResponseDate)