Reputation: 141
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
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
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