简体   繁体   中英

Replace nested ifelse while working with dates in R

Here is my data

sampleData <- structure(list(Category = c("A", "B", "C", "D", "E", "F", "G", 
"H", "I", "J", "K"), Date = structure(c(1546300800, 1547510400, 
1547769600, 1548288000, 1548979200, 1549756800, 1550188800, 1551398400, 
1552348800, 1552608000, 1553472000), class = c("POSIXct", "POSIXt"
), tzone = "UTC")), row.names = c(NA, -11L), class = c("tbl_df", 
"tbl", "data.frame"))

# A tibble: 11 x 2
Category Date               
<chr>    <dttm>             
1 A        2019-01-01 
2 B        2019-01-15 
3 C        2019-01-18 
4 D        2019-01-24 
5 E        2019-02-01 
6 F        2019-02-10 
7 G        2019-02-15 
8 H        2019-03-01 
9 I        2019-03-12 
10 J        2019-03-15 
11 K        2019-03-25 
lookupData <- structure(list(`Original Date` = structure(c(1546560000, 1547769600, 
1548979200, 1550188800, 1551398400, 1552608000, 1553817600, 1555027200, 
1556236800, 1557446400, 1558656000, 1559865600), class = c("POSIXct", 
"POSIXt"), tzone = "UTC")), row.names = c(NA, -12L), class = c("tbl_df", 
"tbl", "data.frame"))

# A tibble: 12 x 1
`Original Date`    
<dttm>             
 1 2019-01-04 
 2 2019-01-18 
 3 2019-02-01 
 4 2019-02-15 
 5 2019-03-01 
 6 2019-03-15 
 7 2019-03-29 
 8 2019-04-12 
 9 2019-04-26 
10 2019-05-10 
11 2019-05-24 
12 2019-06-07 

Currently I have multiple ifelse() statements something like this to get this working.

sampleData$ModifiedDate <- ifelse(sampleData$Date <= "2019-01-04", "2019-01-04",
                 ifelse(sampleData$Date <= "2019-01-18", "2019-01-18",
                        ifelse(sampleData$Date <= "2019-02-01", "2019-02-01",
                               ifelse(sampleData$Date <= "2019-02-15", "2019-02-15",
                                      ifelse(sampleData$Date <= "2019-03-01", "2019-03-01",
                                             ifelse(sampleData$Date <= "2019-03-15", "2019-03-15",
                                                    ifelse(sampleData$Date <= "2019-03-29", "2019-03-29",
                                                           ifelse(sampleData$Date <= "2019-04-12", "2019-04-12",
                                                                  ifelse(sampleData$Date <= "2019-04-26", "2019-04-26","")))))))))

This works, but it is not the way I would want it. Is there a more efficient way to do this? I tried the merge() and fuzzy_left_join() options but I don't get the desired results like below.

在此处输入图像描述

Here's an attempt with fuzzyjoin :

library(dplyr)

lookupData %>%
  mutate(z = lag(`Original Date`, default = as.POSIXct("1970-01-01"))) %>%
  fuzzyjoin::fuzzy_left_join(
    sampleData, .,
    by = c(Date = "z", Date = "Original Date"),
    match_fun = list(`>`, `<=`)) %>%
  select(-z)
# # A tibble: 11 x 3
#    Category Date                `Original Date`    
#    <chr>    <dttm>              <dttm>             
#  1 A        2019-01-01 00:00:00 2019-01-04 00:00:00
#  2 B        2019-01-15 00:00:00 2019-01-18 00:00:00
#  3 C        2019-01-18 00:00:00 2019-01-18 00:00:00
#  4 D        2019-01-24 00:00:00 2019-02-01 00:00:00
#  5 E        2019-02-01 00:00:00 2019-02-01 00:00:00
#  6 F        2019-02-15 00:00:00 2019-02-15 00:00:00
#  7 G        2019-02-10 00:00:00 2019-02-15 00:00:00
#  8 H        2019-03-12 00:00:00 2019-03-15 00:00:00
#  9 I        2019-03-01 00:00:00 2019-03-01 00:00:00
# 10 J        2019-03-15 00:00:00 2019-03-15 00:00:00
# 11 K        2019-03-25 00:00:00 2019-03-29 00:00:00

This would be better served with a formula as it appears you are advancing all dates to the following, 2nd Friday. If that is correct then the following will accomplish that and does not matter how long the dates span.

Setting baseDate that is used to determine what is the first date for reference:

baseDate <- structure(1546560000, class = c("POSIXct", "POSIXt"), tzone = "UTC")

Using ceiling to advance the date to the following, 2nd Friday:

sampleData$NewDate <-  baseDate + ceiling((sampleData$Date - baseDate) / 14) * 14

   Category       Date    NewDate
1         A 2019-01-01 2019-01-04
2         B 2019-01-15 2019-01-18
3         C 2019-01-18 2019-01-18
4         D 2019-01-24 2019-02-01
5         E 2019-02-01 2019-02-01
6         F 2019-02-15 2019-02-15
7         G 2019-02-10 2019-02-15
8         H 2019-03-12 2019-03-15
9         I 2019-03-01 2019-03-01
10        J 2019-03-15 2019-03-15
11        K 2019-03-25 2019-03-29

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM