【问题标题】:R fill in new column by filtered value by groupR按组过滤值填充新列
【发布时间】:2020-09-20 16:07:20
【问题描述】:

我想在我的dat 中创建新列,用值填充 满足一个条件。所以,我想保留value where regime == "SA" 并将这个值填充到新列vals.sa 的整个组中。

这结合了filtermutate,但我不确定它们的正确组合是什么? Filter 只是保持满足条件的行,但是如何将这个值扩展到组中的所有行?

我的数据:

dat <- data.frame(id = c(1,1,2,2,2,2,3,3),
                  regime = c("SA", "B", "SA", "B", "C", "F", "SA", "D"),
                  value = c(3,5,1,2,5,6,7,8))

使用dplyr处理数据

dat %>% 
  # group data by id
  group_by(id) %>%           
  # how to write this condition and get values instead or TRUE/FALSE?
  mutate(val.sa = regime == "SA") 

填入val.sa值对应regime == "SA"的预期输出

     id regime value val.sa
  <dbl> <fct>  <dbl>  <dbl>
1     1 SA         3      3
2     1 B          5      3
3     2 SA         1      1
4     2 B          2      1
5     2 C          5      1
6     2 F          6      1
7     3 SA         7      7
8     3 D          8      7

【问题讨论】:

    标签: r filter dplyr expand


    【解决方案1】:

    你可以使用:

    library(dplyr)
    dat %>%
      group_by(id) %>%
      mutate(value.sa = value[regime == 'SA'])
      #OR
      #mutate(value.sa = value[match('SA', regime)])
    
    
    #     id regime value value.sa
    #  <dbl> <chr>  <dbl>    <dbl>
    #1     1 SA         3        3
    #2     1 B          5        3
    #3     2 SA         1        1
    #4     2 B          2        1
    #5     2 C          5        1
    #6     2 F          6        1
    #7     3 SA         7        7
    #8     3 D          8        7
    

    如果一个组中可能有多个regime 的值为"SA",您可以使用which.max/match 选择第一个值。

    dat %>%
      group_by(id) %>%
      mutate(value.sa = value[which.max(regime == 'SA')])
    

    【讨论】:

      【解决方案2】:

      如果您一直只有一个 SA 在每个组中,这应该运行没有任何错误:

      dat %>% 
        group_by(id) %>%             
        mutate(val.sa = value[regime == "SA"]) 
      #> # A tibble: 8 x 4
      #> # Groups:   id [3]
      #>      id regime value val.sa
      #>   <dbl> <fct>  <dbl>  <dbl>
      #> 1     1 SA         3      3
      #> 2     1 B          5      3
      #> 3     2 SA         1      1
      #> 4     2 B          2      1
      #> 5     2 C          5      1
      #> 6     2 F          6      1
      #> 7     3 SA         7      7
      #> 8     3 D          8      7
      

      否则,您必须决定要保留哪个SA-value。例如始终保持最大值:

      dat <- data.frame(id = c(1,1,2,2,2,2,3,3),
                        regime = c("SA", "B", "SA", "SA", "C", "F", "SA", "D"),
                        value = c(3,5,1,2,5,6,7,8))
      dat
      #>   id regime value
      #> 1  1     SA     3
      #> 2  1      B     5
      #> 3  2     SA     1
      #> 4  2     SA     2
      #> 5  2      C     5
      #> 6  2      F     6
      #> 7  3     SA     7
      #> 8  3      D     8
      
      dat %>% 
        group_by(id) %>%             
        mutate(val.sa = max(value[regime == "SA"]))
      #> # A tibble: 8 x 4
      #> # Groups:   id [3]
      #>      id regime value val.sa
      #>   <dbl> <fct>  <dbl>  <dbl>
      #> 1     1 SA         3      3
      #> 2     1 B          5      3
      #> 3     2 SA         1      2
      #> 4     2 SA         2      2
      #> 5     2 C          5      2
      #> 6     2 F          6      2
      #> 7     3 SA         7      7
      #> 8     3 D          8      7
      

      【讨论】:

        【解决方案3】:

        首先创建一个新列val.saSA 行中的值等于value 列中的值。然后按idfill 分组。像这样:

        dat %>%
          mutate(val.sa = ifelse(regime == 'SA', value, NA)) %>%
          group_by(id) %>%
          fill(val.sa)
        ## A tibble: 8 x 4
        ## Groups:   id [3]
        #     id regime value val.sa
        #  <dbl> <chr>  <dbl>  <dbl>
        #1     1 SA         3      3
        #2     1 B          5      3
        #3     2 SA         1      1
        #4     2 B          2      1
        #5     2 C          5      1
        #6     2 F          6      1
        #7     3 SA         7      7
        #8     3 D          8      7
        

        【讨论】:

          【解决方案4】:

          我们可以使用case_when

          library(dplyr)
          library(tidyr)
           dat %>%
               mutate(val.sa = case_when(regime == 'SA' ~ value) %>%
               group_by(id) %>%
               fill(val.sa)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-01-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-06-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多