【问题标题】:How to loop ifelse function through a grouped variable with dplyr如何使用 dplyr 通过分组变量循环 ifelse 函数
【发布时间】:2020-11-27 18:24:05
【问题描述】:

我正在尝试为一组 ID 应用一个规则,在第一个实例中,一个变量的值等于 1,该组中所有后续行中另一个变量的所有值都等于 1。

基本上,这就是我想要做的:

我有:

ID D
1  1
1  0
1  0
2  0
2  0
3  1
3  0
3  0
4  1
4  0
4  1
4  1
4  1
4  0

我想要:

ID D PREV
1  1  0
1  0  1
1  0  1
2  0  0
2  0  0
3  1  0
3  0  1
3  0  1
4  1  0
4  0  1
4  1  1
4  1  1
4  0  1

我正在尝试使用 dplyr 遍历一系列分组的行,在每个行中应用一个 ifelse 函数。我的代码如下所示:

data$prev = 0
data <-   
data %>%
group_by(id)%>%
mutate(prev = if_else(lag(prev) == 1 | lag(d) == 1, 1, 0))

但由于某种原因,这并没有将 ifelse 函数应用于整个组,导致数据看起来像这样:

ID D PREV
1  1  0
1  0  1
1  0  0
2  0  0
2  0  0
3  1  0
3  0  1
3  0  0
4  1  0
4  0  1
4  1  0
4  1  1
4  0  1

谁能帮我解决这个问题?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这个呢:

    library(dplyr)
    df %>% 
     group_by(ID) %>% 
     mutate(prev = +(cumsum(c(0, D[-length(D)])) > 0)) %>% 
     ungroup()
    
    #> # A tibble: 14 x 3
    #>       ID     D  prev
    #>    <int> <int> <int>
    #>  1     1     1     0
    #>  2     1     0     1
    #>  3     1     0     1
    #>  4     2     0     0
    #>  5     2     0     0
    #>  6     3     1     0
    #>  7     3     0     1
    #>  8     3     0     1
    #>  9     4     1     0
    #> 10     4     0     1
    #> 11     4     1     1
    #> 12     4     1     1
    #> 13     4     1     1
    #> 14     4     0     1
    

    为了解释它的作用,我们只看一个简单的向量。 每个组的计算结果都相同。

    成为x我们的向量

    x <- c(0,0,0,1,1,0,0,2,3,4)
    

    x求和

    cumsum(x)
    #>  [1]  0  0  0  1  2  2  2  4  7 11
    

    您只对高于零的值感兴趣,因此:

    cumsum(x)>0
    #>  [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
    

    您不需要逻辑,而是数字。只需 + 就可以了

    +(cumsum(x)>0)
    #>  [1] 0 0 0 1 1 1 1 1 1 1
    

    但是,您希望将 1 延迟 1。因此,我们在 x 之上有一个零

    +(cumsum(c(0,x))>0)
    #>  [1] 0 0 0 0 1 1 1 1 1 1 1
    

    我们需要保持相同的长度,所以我们删除了x的最后一个值。

    +(cumsum(c(0, x[-length(x)])) > 0)
    #>  [1] 0 0 0 0 1 1 1 1 1 1
    

    这就是诀窍。

    【讨论】:

    • 这成功了!这是如何达到我想要的效果的?
    • 我添加了一个编辑来解释它的作用
    • 但是,@akrun 解决方案更好。您应该使用该代码! :-)
    【解决方案2】:

    我们可以使用lag

    library(dplyr)
    df %>% 
       group_by(ID) %>%
       mutate(prev = lag(cumsum(D) > 0, default = 0))
    

    -输出

    # A tibble: 14 x 3
    # Groups:   ID [4]
    #      ID     D  prev
    #   <dbl> <dbl> <dbl>
    # 1     1     1     0
    # 2     1     0     1
    # 3     1     0     1
    # 4     2     0     0
    # 5     2     0     0
    # 6     3     1     0
    # 7     3     0     1
    # 8     3     0     1
    # 9     4     1     0
    #10     4     0     1
    #11     4     1     1
    #12     4     1     1
    #13     4     1     1
    #14     4     0     1
    

    数据

    df <- data.frame(
        ID = c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4),
        D = c(1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0)
    )
    

    【讨论】:

      【解决方案3】:

      您可以使用 dplyr dplyr::group_modify 的新函数将函数应用于组

      df <- data.frame(
          ID = c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4),
          D = c(1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0)
      )
      
      df %>% group_by(ID) %>% group_modify(
          function(x, y){
              boo <- x[1, ]$D == 1
              ifelse(boo, 
                     {x$prev = 1
                      x$prev[1] = 0
                     },
                     {x$prev = 0})
              
              x
          }
      )
      
      # A tibble: 14 x 3
      # Groups:   ID [4]
            ID     D  prev
         <dbl> <dbl> <dbl>
       1     1     1     0
       2     1     0     1
       3     1     0     1
       4     2     0     0
       5     2     0     0
       6     3     1     0
       7     3     0     1
       8     3     0     1
       9     4     1     0
      10     4     0     1
      11     4     1     1
      12     4     1     1
      13     4     1     1
      14     4     0     1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-03
        • 2016-07-30
        • 2018-11-23
        相关资源
        最近更新 更多