Reputation: 446
I would like to mutate specific rows while evaluating the mutation on multiple rows that would remain outside the boundaries of a simple filter()
. How can I do?
df <-
data.frame(ID = c(1,1,1,2,2,2,3,3,3),
Date= c(1,2,3,1,2,3,1,2,3),
Money = c(500,400,500,5000,100,100,200,300,300),
Status = c("Good", "Bad", "Good", "Good","Good","Good", "Bad","Good","Good"))
For example I want to mutate(Money = max(Money))
at Date==1
but at the same time I don't want to drop other variables or perform the mutation on all grouping dates. Is there any way?
The result should be as in the below table.
result <-
data.frame(ID = c(1,1,1,2,2,2,3,3,3),
Date= c(1,2,3,1,2,3,1,2,3),
Money = c(5000,400,500,5000,100,100,5000,300,300),
Status = c("Good", "Bad", "Good", "Good","Good","Good", "Bad","Good","Good"),
Status_overall = c("Bad", "Bad", "Bad", "Good","Good","Good", "Bad","Bad","Bad"))
Upvotes: 0
Views: 1383
Reputation: 887691
We can use case_when
library(dplyr)
df %>%
mutate(Money = case_when(Date == 1 ~ max(Money), TRUE ~ Money))
# ID Date Money Status
#1 1 1 5000 Good
#2 1 2 400 Bad
#3 1 3 500 Good
#4 2 1 5000 Good
#5 2 2 100 Good
#6 2 3 100 Good
#7 3 1 5000 Bad
#8 3 2 300 Good
#9 3 3 300 Good
Upvotes: 0
Reputation: 39613
Maybe try this. You can store the maximum in a new variable and then mutate by group using a conditional. I do not know where the last variable in your outcome comes:
library(dplyr)
#Code
new <- df %>% mutate(Val=max(Money)) %>%
group_by(ID) %>% mutate(Money=ifelse(Date==1,Val,Money)) %>%
select(-Val)
Output:
# A tibble: 9 x 4
# Groups: ID [3]
ID Date Money Status
<dbl> <dbl> <dbl> <fct>
1 1 1 5000 Good
2 1 2 400 Bad
3 1 3 500 Good
4 2 1 5000 Good
5 2 2 100 Good
6 2 3 100 Good
7 3 1 5000 Bad
8 3 2 300 Good
9 3 3 300 Good
Maybe the simply way without complexity could be (Suggested by @GregorThomas):
#Code2
new <- df %>% mutate(Money=ifelse(Date==1,max(Money),Money))
Output:
ID Date Money Status
1 1 1 5000 Good
2 1 2 400 Bad
3 1 3 500 Good
4 2 1 5000 Good
5 2 2 100 Good
6 2 3 100 Good
7 3 1 5000 Bad
8 3 2 300 Good
9 3 3 300 Good
Upvotes: 1