【问题标题】:A computation efficient way to find the IDs of the Type 1 rows just above and below each Type 2 rows?一种计算有效的方法来查找每个 Type 2 行上方和下方的 Type 1 行的 ID?
【发布时间】:2021-09-01 19:35:30
【问题描述】:

我有以下数据

df <- tibble(Type=c(1,2,2,1,1,2),ID=c(6,4,3,2,1,5)) 

Type ID
1    6
2    4
2    3
1    2
1    1
2    5

对于类型 2 的每一行,我想找到它们正下方和上方的类型 1 行的 ID。对于上述数据集,输出将是:

Type ID IDabove IDbelow
1    6  NA      NA
2    4  6       2
2    3  6       2
1    2  NA      NA
1    1  NA      NA
2    5  1       NA

天真地,我可以编写一个 for 循环来实现这一点,但这对于我正在处理的数据集来说太耗时了。

【问题讨论】:

    标签: r algorithm sorting


    【解决方案1】:

    一种方法使用dplyrlead,lag 分别获取下一个和上一个值,并使用data.tablerleid 创建连续的Type 值组。

    library(dplyr)
    library(data.table)
    
    df %>%
      mutate(IDabove = ifelse(Type == 2, lag(ID), NA), 
             IDbelow = ifelse(Type == 2, lead(ID), NA), 
             grp = rleid(Type)) %>%
      group_by(grp) %>%
      mutate(IDabove = first(IDabove), 
             IDbelow = last(IDbelow)) %>%
      ungroup() %>%
      select(-grp)
    
    #   Type    ID IDabove IDbelow
    #  <dbl> <dbl>   <dbl>   <dbl>
    #1     1     6      NA      NA
    #2     2     4       6       2
    #3     2     3       6       2
    #4     1     2      NA      NA
    #5     1     1      NA      NA
    #6     2     5       1      NA
    

    【讨论】:

    • 这太棒了!
    【解决方案2】:

    dplyr 唯一的解决方案:

    您可以创建自己的rleid 函数,然后应用 Ronak 提供的逻辑(非常感谢。赞成)。

    library(dplyr)
    
    my_func <- function(x) {
      x <- rle(x)$lengths
      rep(seq_along(x), times=x)
    }
    
    # this part is the same as provided by Ronak.
    df %>%
      mutate(IDabove = ifelse(Type == 2, lag(ID), NA), 
             IDbelow = ifelse(Type == 2, lead(ID), NA), 
             grp = my_func(Type)) %>% 
      group_by(grp) %>%
      mutate(IDabove = first(IDabove), 
             IDbelow = last(IDbelow)) %>%
      ungroup() %>%
      select(-grp)
    

    输出:

       Type    ID IDabove IDbelow
      <dbl> <dbl>   <dbl>   <dbl>
    1     1     6      NA      NA
    2     2     4       6       2
    3     2     3       6       2
    4     1     2      NA      NA
    5     1     1      NA      NA
    6     2     5       1      NA
    

    【讨论】:

      猜你喜欢
      • 2019-12-25
      • 1970-01-01
      • 2019-12-05
      • 2023-04-11
      • 1970-01-01
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      • 2016-09-05
      相关资源
      最近更新 更多