代码之家  ›  专栏  ›  技术社区  ›  Lonewolf

基于条件修改特定变量的值

r
  •  1
  • Lonewolf  · 技术社区  · 7 年前

          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
    

    下面是我想要的输出。

         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 
    

    2 回复  |  直到 7 年前
        1
  •  4
  •   s_baldur    7 年前

    使用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
    

    在哪里?

    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
    )
    

    编辑

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

    编辑2

    正如Ronak建议的那样,您可以使用base R附带的ave()执行如下操作:

    data$rating <- 
      ifelse(ave(data$rating == "F", data$ID, FUN = cumsum), "F", data$rating) 
    
        2
  •  1
  •   akrun    7 年前

    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