Lonewolf
Lonewolf

Reputation: 197

Modifying the value for a particular variable based on a condition

I am trying to get the output below, but I do not know how to get it in R. This is the data I have:

      ID    PERIOD     rating
       8      0         3
       8      1         3
       8      2         2
       8      3         F
       8      4         3
       8      5         F
       8      6         1
       9      0         2
       9      1         2
       9      2         1

Below is the output I want.

     ID    PERIOD     rating
      8      0         3
      8      1         3
      8      2         2
      8      3         F
      8      4         F
      8      5         F
      8      6         F
      9      0         2
      9      1         2
      9      2         1 

As you can see, As soon as the rating hit "F" for a particular ID then the rating should remain "F" for that ID. I do not know how to go about coding. Any help will be appreciated.

Upvotes: 1

Views: 44

Answers (2)

akrun
akrun

Reputation: 886948

Here is an option

library(dplyr)
data %>% 
     group_by(ID) %>% 
     mutate(rating  = replace(rating, row_number() > which(rating == "F")[1], "F" ))
# A tibble: 10 x 3
# Groups:   ID [2]
#      ID PERIOD rating
#   <int>  <int> <chr> 
# 1     8      0 3     
# 2     8      1 3     
# 3     8      2 2     
# 4     8      3 F     
# 5     8      4 F     
# 6     8      5 F     
# 7     8      6 F     
# 8     9      0 2     
# 9     9      1 2     
#10     9      2 1     

Upvotes: 1

s_baldur
s_baldur

Reputation: 33498

Using data.table:

setDT(data)

data[, rating := ifelse(cumsum(rating == "F") >= 1, "F", rating), by = ID]

data
    ID PERIOD rating
 1:  8      0      3
 2:  8      1      3
 3:  8      2      2
 4:  8      3      F
 5:  8      4      F
 6:  8      5      F
 7:  8      6      F
 8:  9      0      2
 9:  9      1      2
10:  9      2      1

Where

data <- data.frame(
  ID = c(8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L), 
  PERIOD = c(0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L), 
  rating = c("3", "3", "2", "F", "3", "F", "1", "2", "2", "1"),
  stringsAsFactors = FALSE
)

EDIT

Long story, but this could be made more concise:

data[, rating := ifelse(cumsum(rating == "F"), "F", rating), by = ID]

EDIT 2

As Ronak's suggests you could do something like the following using ave() that comes with base R:

data$rating <- 
  ifelse(ave(data$rating == "F", data$ID, FUN = cumsum), "F", data$rating) 

Upvotes: 4

Related Questions