LDT
LDT

Reputation: 3088

Mutate the values of a specific group in your data with dplyr in R

My data frame looks like this

value <- c(0,0.1,0.2,0.4,0,0.05,0.05,0.5,0.20,0.40,0.50,0.60)
time <- c(1,1,1,1,2,2,2,2,3,3,3,3)
ID <- c(1,2,3,4,1,2,3,4,1,2,3,4)

test <- data.frame(value, time, ID)
test

   value time ID
1   0.00    1  1
2   0.10    1  2
3   0.20    1  3
4   0.40    1  4
5   0.00    2  1
6   0.05    2  2
7   0.05    2  3
8   0.50    2  4
9   0.20    3  1
10  0.40    3  2
11  0.50    3  3
12  0.60    3  4

In this example, I would subtract the values of time==2 with 1 and my data to look like this something like mutate(time[time==2]= time[time==2] -1) which of course is not possible

   value time ID
1   0.00    1  1
2   0.10    1  2
3   0.20    1  3
4   0.40    1  4
5   0.00    1  1
6   0.05    1  2
7   0.05    1  3
8   0.50    1  4
9   0.20    3  1
10  0.40    3  2
11  0.50    3  3
12  0.60    3  4

Any hint and help are highly appreciated

EDIT

One way would be to replace the value but how could I subtract it? mutate(time=replace(time, time==2, 1))

Upvotes: 1

Views: 69

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 388982

To subtract time value by 1 when time == 2 you can do :

library(dplyr)

test %>% mutate(time= time - as.integer(time == 2))

#   value time ID
#1   0.00    1  1
#2   0.10    1  2
#3   0.20    1  3
#4   0.40    1  4
#5   0.00    1  1
#6   0.05    1  2
#7   0.05    1  3
#8   0.50    1  4
#9   0.20    3  1
#10  0.40    3  2
#11  0.50    3  3
#12  0.60    3  4

Upvotes: 1

DaveArmstrong
DaveArmstrong

Reputation: 21937

You can use case_when() to do this. The code below will replace time with 1 when time is equal to 2 and returns the value of time otherwise. Note that this doesn't look exactly like your desired output because this generates ones and threes instead of zeros and ones.

library(dplyr)
test <- test %>% 
  mutate(time = case_when(
    time == 2 ~ 1, 
    TRUE ~ time
  ))
test
#    value time ID
# 1   0.00    1  1
# 2   0.10    1  2
# 3   0.20    1  3
# 4   0.40    1  4
# 5   0.00    1  1
# 6   0.05    1  2
# 7   0.05    1  3
# 8   0.50    1  4
# 9   0.20    3  1
# 10  0.40    3  2
# 11  0.50    3  3
# 12  0.60    3  4

To produce something that looks exactly like the desired output above, you would need:

test <- test %>% 
  mutate(time = case_when(
    time == 1 ~ 0, 
    TRUE ~ 1
  ))
test
#    value time ID
# 1   0.00    0  1
# 2   0.10    0  2
# 3   0.20    0  3
# 4   0.40    0  4
# 5   0.00    0  1
# 6   0.05    0  2
# 7   0.05    0  3
# 8   0.50    0  4
# 9   0.20    1  1
# 10  0.40    1  2
# 11  0.50    1  3
# 12  0.60    1  4

Upvotes: 1

Related Questions