代码之家  ›  专栏  ›  技术社区  ›  jakes

定义基于变量运行的序列,并附加来自另一个变量的条件

  •  1
  • jakes  · 技术社区  · 6 年前
    structure(list(group = c(NA, "A", "B", NA, "B", "B", "B", "B", 
    "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
    "B", NA, NA, "B", "B", "A", "A", NA, NA, "B", "B", "B", NA, "A", 
    "A", "A", "A", "A", "A", "A", "A", "A", "A", NA, NA, "B", "B", 
    NA, "A"), seq_break = c(TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, 
    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
    TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, 
    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE)), .Names = c("group", 
    "seq_break"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
    -50L))
    

    group 列(如 data.table::rleid 产生,但忽略 NA ). 正如你所看到的,我们还有一个专栏 seq_break 它应该结束一个序列。通常是这样的,就像 group = NA 然后 seq_break = TRUE . 但有时 seq\ u break=真 A B -然后,即使下一行引用同一个组,也应该结束序列并开始新的序列。例如,行 25:26 我们应该有两个不同的序列id,即使两个事件都指向组 . 一般情况下,预期产量如下所示:

    structure(list(group = c(NA, "A", "B", NA, "B", "B", "B", "B", 
    "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
    "B", NA, NA, "B", "B", "A", "A", NA, NA, "B", "B", "B", NA, "A", 
    "A", "A", "A", "A", "A", "A", "A", "A", "A", NA, NA, "B", "B", 
    NA, "A"), seq_break = c(TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, 
    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, 
    TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, 
    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE), expected_output = c(NA, 
    1, 2, NA, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    3, NA, NA, 4, 5, 6, 6, NA, NA, 7, 7, 7, NA, 8, 8, 8, 8, 8, 8, 
    8, 8, 8, 8, NA, NA, 11, 11, NA, 12)), .Names = c("group", "seq_break", 
    "expected_output"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
    -50L))
    

    我怎样才能做到这一点 tidyverse ?

    1 回复  |  直到 6 年前
        1
  •  2
  •   www    6 年前

    使用 tidyverse data.table . 假设 dt1 是您的示例数据帧和 dt3 是最终输出。注意,我认为在预期的输出中,第47到48行应该是9,第50行应该是10。我不知道为什么在预期的输出中,第47到48行是11,第50行是12。

    library(tidyverse)
    library(data.table)
    
    dt2 <- dt1 %>% rowid_to_column() 
    
    dt3 <- dt2 %>%
      mutate(ID = rleid(group, seq_break)) %>%
      group_by(group, seq_break, ID) %>%
      filter(!(is.na(group) & seq_break & row_number() > 1)) %>%
      ungroup() %>%
      mutate(ID2 = cumsum(seq_break)) %>%
      drop_na(group) %>%
      mutate(expected_output = rleid(group, ID2)) %>%
      select(rowid, expected_output) %>%
      left_join(dt2, ., by = "rowid") %>%
      select(-rowid)
    
    dt3
    # # A tibble: 50 x 3
    #    group seq_break expected_output
    #    <chr> <lgl>               <int>
    #  1 NA    TRUE                   NA
    #  2 A     FALSE                   1
    #  3 B     FALSE                   2
    #  4 NA    TRUE                   NA
    #  5 B     FALSE                   3
    #  6 B     FALSE                   3
    #  7 B     FALSE                   3
    #  8 B     FALSE                   3
    #  9 B     FALSE                   3
    # 10 B     FALSE                   3
    # # ... with 40 more rows