【问题标题】:replacing zeros with one in R conditional on the values befomre and after以 R 中的 1 替换零,条件是之前和之后的值
【发布时间】:2022-01-15 18:43:55
【问题描述】:

我有一个数据框如下:

df_ex <- tibble(
  id = c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2), 
  flag = c(1,0,0,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0),
  flag_new = c(1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0)
)

假设我有一个名为 flag 的变量,因此对于每个 id,我想检查该变量中的零之间的数量。如果我有一个并且最多有 4 个零,然后还有另一个,我想用 1 替换零(在这些之间)。我创建了一个名为 flag_new 的变量,这是我要生成的真正标志。

提前感谢您的帮助。

【问题讨论】:

    标签: r replace


    【解决方案1】:

    一种选择是创建一个带有rle 的函数,找到1s 的min/max 索引并在按'id' 分组后应用于'flag' 列

    library(dplyr)
      
    f1 <- function(x, n = 4) {
       x1 <- rle(x)
       i1 <- x1$lengths <= 4 & x1$values == 0 & 
          !seq_along(x1$values) %in% c(1, length(x1$values))
       x1$values[i1] <- 1
      inverse.rle(x1)
     }
    df_ex %>% 
       group_by(id) %>% 
       mutate(flag_new2 = f1(flag, 4)) %>%
       ungroup
    

    -输出

    # A tibble: 18 × 4
          id  flag flag_new flag_new2
       <dbl> <dbl>    <dbl>     <dbl>
     1     1     1        1         1
     2     1     0        1         1
     3     1     0        1         1
     4     1     1        1         1
     5     1     1        1         1
     6     1     0        0         0
     7     1     0        0         0
     8     1     0        0         0
     9     2     1        1         1
    10     2     1        1         1
    11     2     0        1         1
    12     2     0        1         1
    13     2     1        1         1
    14     2     0        0         0
    15     2     0        0         0
    16     2     0        0         0
    17     2     0        0         0
    18     2     0        0         0
    

    -测试1s之间0个数大于4个时

    > df_ex$flag[10:16] <- 0
    > df_ex$flag[17] <- 1
    > df_ex %>% 
    +    group_by(id) %>% 
    +    mutate(flag_new2 = f1(flag, 4)) %>%
    +    ungroup
    # A tibble: 18 × 4
          id  flag flag_new flag_new2
       <dbl> <dbl>    <dbl>     <dbl>
     1     1     1        1         1
     2     1     0        1         1
     3     1     0        1         1
     4     1     1        1         1
     5     1     1        1         1
     6     1     0        0         0
     7     1     0        0         0
     8     1     0        0         0
     9     2     1        1         1
    10     2     0        1         0
    11     2     0        1         0
    12     2     0        1         0
    13     2     0        1         0
    14     2     0        0         0
    15     2     0        0         0
    16     2     0        0         0
    17     2     1        0         1
    18     2     0        0         0
    

    【讨论】:

    • 感谢您的回复。没有一个解决方案适用于我的真实数据集,并且无论条件如何,它都用 1 替换了所有零(1 之间最多应该有 4 个零)
    • 是对的,应该是这样的。
    • @SeyedHosseini 尝试更新
    • 完美运行@akrun,感谢您的帮助!
    • 我已经这样做了。
    【解决方案2】:

    以下是所提供数据的替代方法:

    1. 0 替换为NA
    2. fill
    3. NA 替换为0
    library(tidyr)
    library(dplyr)
    
    df_ex %>% 
      group_by(id) %>%
      mutate(flag_new1 = na_if(flag, 0)) %>% 
      fill(flag_new1, .direction = "up") %>% 
      mutate(flag_new1 = replace_na(flag_new1, 0)) %>% 
      ungroup()
    
          id  flag flag_new flag_new1
       <dbl> <dbl>    <dbl>     <dbl>
     1     1     1        1         1
     2     1     0        1         1
     3     1     0        1         1
     4     1     1        1         1
     5     1     1        1         1
     6     1     0        0         0
     7     1     0        0         0
     8     1     0        0         0
     9     2     1        1         1
    10     2     1        1         1
    11     2     0        1         1
    12     2     0        1         1
    13     2     1        1         1
    14     2     0        0         0
    15     2     0        0         0
    16     2     0        0         0
    17     2     0        0         0
    18     2     0        0         0
    

    【讨论】:

      猜你喜欢
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2019-06-11
      • 2015-08-24
      • 1970-01-01
      • 2017-11-05
      相关资源
      最近更新 更多