【问题标题】:How to use dplyr to conditionally change values in a column by group?如何使用 dplyr 有条件地按组更改列中的值?
【发布时间】:2019-09-11 23:54:15
【问题描述】:

我有这样的数据:

g1 g2 var 
 1  a Yes 
 1  a No 
 1  a No 
 1  b Yes 
 1  b Yes 
 1  b Yes 
 2  a No 
 2  a No 
 2  a No

如果在每个 g1&g2 组中,var 中至少有一个 Yes,我想将 var 中的所有值更改为 Yes。我尝试使用 group_by 和 mutate、replace、ifelse 的组合但没有成功。任何帮助表示赞赏。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    一种非 case_when if_else 方式,很有趣

    df1 %>% 
    group_by(g1,g2) %>% 
    arrange (g1,g2,var) %>% 
    mutate(var=last(var)) 
    
     # arranged alphabetically, var values may be changed to the last value by groups -- Yes in this case
    
    
             g1 g2    var  
          <int> <chr> <chr>
        1     1 a     Yes  
        2     1 a     Yes  
        3     1 a     Yes  
        4     1 b     Yes  
        5     1 b     Yes  
        6     1 b     Yes  
        7     2 a     No   
        8     2 a     No   
        9     2 a     No   
    

    【讨论】:

    • 非常感谢大家!
    【解决方案2】:

    我们可以使用if/else 代替ifelse。按'g1'、'g2'、if'Yes'分组为%in%'var',则返回“Yes”,否则返回'var'

    library(dplyr)
    df1 %>% 
       group_by(g1, g2) %>% 
       mutate(var = if("Yes" %in% var) "Yes" else var)
    # A tibble: 9 x 3
    # Groups:   g1, g2 [3]
    #     g1 g2    var  
    #  <int> <chr> <chr>
    #1     1 a     Yes  
    #2     1 a     Yes  
    #3     1 a     Yes  
    #4     1 b     Yes  
    #5     1 b     Yes  
    #6     1 b     Yes  
    #7     2 a     No   
    #8     2 a     No   
    #9     2 a     No   
    

    或者case_when

    df1 %>% 
       group_by(g1, g2) %>% 
       mutate(var = case_when("Yes" %in% var ~ "Yes", TRUE ~ var))
    

    数据

    df1 <- structure(list(g1 = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), g2 = c("a", 
     "a", "a", "b", "b", "b", "a", "a", "a"), var = c("Yes", "No", 
     "No", "Yes", "Yes", "Yes", "No", "No", "No")), class = "data.frame", 
      row.names = c(NA, -9L))
    

    【讨论】:

      【解决方案3】:

      上述两个解决方案中的额外代码行,但使用ifelseif_else 创建一个新列,然后删除并重命名:

      library(tidyverse)
      df %>% 
        group_by(g1, g2) %>% 
        mutate(var2 = if_else("Yes" %in% var, "Yes", "No")) %>% 
        select(-var, var = var2)
      

      结果:

           g1 g2    var  
        <dbl> <chr> <chr>
      1     1 a     Yes  
      2     1 a     Yes  
      3     1 a     Yes  
      4     1 b     Yes  
      5     1 b     Yes  
      6     1 b     Yes  
      7     2 a     No   
      8     2 a     No   
      9     2 a     No   `
      

      【讨论】:

        【解决方案4】:

        你也可以这样做:

        df %>%
         group_by(g1, g2) %>%
         mutate(var = ifelse(any(var == "Yes"), "Yes", "No"))
        
             g1 g2    var  
          <int> <chr> <chr>
        1     1 a     Yes  
        2     1 a     Yes  
        3     1 a     Yes  
        4     1 b     Yes  
        5     1 b     Yes  
        6     1 b     Yes  
        7     2 a     No   
        8     2 a     No   
        9     2 a     No   
        

        这里,如果“var”中的任何值(每个“g1”和“g2”)等于Yes,则返回Yes,否则返回No

        【讨论】:

          猜你喜欢
          • 2016-06-07
          • 2022-12-03
          • 2017-08-16
          • 1970-01-01
          • 2022-01-14
          • 1970-01-01
          • 1970-01-01
          • 2020-09-11
          • 1970-01-01
          相关资源
          最近更新 更多