luis vergara
luis vergara

Reputation: 141

If statements and Dates

What I am trying to achieve is allocate a new column with a variable that changes over time. It is just one of them that is changing so what I would like to do is After (date) put 40 instead if 22

I currently have this Code that is not working properly

Idea:
    if(lst$taskDate <= as.Date("2018-11-18")){
    t2$Budget <- case_when(
        t2$taskStaffName == "L" ~ 20,
        t2$taskStaffName == "J" ~ 22,
        TRUE ~ 40
    )
    }else{
        if(lst$taskDate >= as.Date("2018-11-19"))
    t2$Budget <- case_when(
        t2$taskStaffName == "L" ~ 20,
        t2$taskStaffName == "J" ~ 40,
                TRUE ~ 40

    )
        }


This is the Data Sample:

# A tibble: 3,692 x 4
   taskStaffName taskDate   taskMinutes taskBillable
   <chr>         <date>     <chr>       <chr>       
 1 G             2018-07-02 300         true        
 2 G             2018-07-02 180         true        
 3 L             2018-07-02 300         true        
 4 L             2018-07-02 180         false       
 5 C             2018-07-02 360         false       
 6 C             2018-07-02 120         false       
 7 G             2018-07-03 480         true        
 8 L             2018-07-03 30          true        
 9 L             2018-07-03 180         true        
10 L             2018-07-02 30          true        
# ... with 3,682 more rows



Desired Outcome:

# A tibble: 3,692 x 5
   taskStaffName taskDate   taskMinutes taskBillable Budget
   <chr>         <date>     <chr>       <chr>         <dbl>
 1 J             2018-07-02 300         true             22
 2 J             2018-07-02 180         true             22
 3 L             2018-07-02 300         true             20
 4 L             2018-07-02 180         false            20
 5 C             2018-07-02 360         false            40
 6 C             2018-07-02 120         false            40
 7 L             2018-07-03 480         true             20
 8 L             2018-07-03 30          true             20
 9 J             2018-11-19 180         true             40
10 J             2018-11-19 30          true             40
# ... with 3,682 more rows

Upvotes: 0

Views: 1042

Answers (2)

luis vergara
luis vergara

Reputation: 141

As Gregor have mentioned I just used case_when for this problem.

I end it up using this code:

lst2$Budget <- case_when(
    lst$taskStaffName == "L"  ~ 20,
    lst$taskStaffName == "J" & lst$taskDate <= as.Date("2018-11-18") ~ 22,
    lst$taskStaffName == "J" & lst$taskDate > as.Date("2018-11-18") ~ 40,
    TRUE ~ 40
)

thank you all for taking some time out and trying to solve my question!

Upvotes: 0

r2evans
r2evans

Reputation: 160952

I infer from this that you will have different before/after rates for each taskStaffName, so it might be better to rethink how you approach the problem. Instead of doing a case_when (or worse, ifelse) including every combination of name and date, merge in a frame of before/after rates and use the appropriate field.

x <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
   taskStaffName taskDate   taskMinutes taskBillable
 1 G             2018-07-02 300         true        
 2 G             2018-07-02 180         true        
 3 L             2018-07-02 300         true        
 4 L             2018-07-02 180         false       
 5 C             2018-07-02 360         false       
 6 C             2018-07-02 120         false       
 7 G             2018-07-03 480         true        
 8 L             2018-07-03 30          true        
 9 L             2018-07-03 180         true        
10 L             2018-07-02 30          true        ")
x$taskDate <- as.Date(x$taskDate)

library(dplyr)
# library(tibble)
taskRates <- tibble::tribble(
  ~taskStaffName, ~before, ~after
 ,"J"           ,      22,     40
 ,"L"           ,      20,     20
 ,"G"           ,      20,     41
 ,"C"           ,      40,     41
)

cutoffDate <- as.Date("2018-11-18")
x %>%
  left_join(taskRates, by = "taskStaffName") %>%
  mutate(Budget = if_else(taskDate <= cutoffDate, before, after)) %>%
  select(-before, -after)
#    taskStaffName   taskDate taskMinutes taskBillable Budget
# 1              G 2018-07-02         300         true     20
# 2              G 2018-07-02         180         true     20
# 3              L 2018-07-02         300         true     20
# 4              L 2018-07-02         180        false     20
# 5              C 2018-07-02         360        false     40
# 6              C 2018-07-02         120        false     40
# 7              G 2018-07-03         480         true     20
# 8              L 2018-07-03          30         true     20
# 9              L 2018-07-03         180         true     20
# 10             L 2018-07-02          30         true     20

This hard-supposes a single interesting cutoff date. If you are planning on having a multi-month schedule of rates, then this problem should probably be revisited, since you might be better off with a conditional join (e.g., range-join, fuzzy-join). Refs:


Edit

If your logic is never going to be more complex than 1 user changing on a date, then you can use the case_when logic as @Gregor previously recommended:

x %>%
  mutate(
    Budget = case_when(
      taskStaffName == "L"     ~ 20,
      taskStaffName == "J" &
        taskDate <= cutoffDate ~ 20,
      TRUE                     ~ 40
    )
  )
#    taskStaffName   taskDate taskMinutes taskBillable Budget
# 1              G 2018-07-02         300         true     40
# 2              G 2018-07-02         180         true     40
# 3              L 2018-07-02         300         true     20
# 4              L 2018-07-02         180        false     20
# 5              C 2018-07-02         360        false     40
# 6              C 2018-07-02         120        false     40
# 7              G 2018-07-03         480         true     40
# 8              L 2018-07-03          30         true     20
# 9              L 2018-07-03         180         true     20
# 10             L 2018-07-02          30         true     20

Upvotes: 1

Related Questions