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

解析R中的数据并创建一个标志

  •  0
  • Sarah  · 技术社区  · 2 年前

    这段代码在我看来非常简单,但我在逻辑上遇到了问题。

    我有一个包含2列(ID和年份)的数据框架。我想创建一个名为“FLAG”的第三列,它的输出基于以下条件 (全部按ID分组) :

    • 如果存在2020年或2021年的数据(但不是两者都有),则输出“差距”
    • 如果存在2020年和2021年的数据,则输出“Ap21”
    • 如果存在2020年、2021年和2022年的数据,则输出“Ap22”
    • 如果2020年和2021年的数据都不存在(或任何其他不符合上述3个条件的情况),则输出“未更新”

    我举了一个例子,说明我希望我的数据帧最终看起来如何。

      data <- data.frame("ID" = c("A", "A", "A", "B", "B", "B", "C", "C", "C", "C", "D", "D"),  
      Year" = c(2019, 2021, 2022, 2019, 2020, 2021, 2019, 2020, 2021, 2022, 2018, 2019), "Flag" 
      = c("Gap", "Gap", "Gap", "Ap21", "Ap21", "Ap21", "Ap22", "Ap22", "Ap22", "Ap22", 
      "notupdated", "notupdated"))
    

    非常感谢!

    3 回复  |  直到 2 年前
        1
  •  5
  •   Jan    2 年前

    A. dplyr 解决方案

    library(dplyr)
    
    data |>
      mutate(
        Flag = case_when(
          all(c(2020, 2021, 2022) %in% Year) ~ "Ap22",
          all(c(2020, 2021) %in% Year) ~ "Ap21",
          any(c(2020, 2021) %in% Year) ~ "Gap",
          .default = "notupdated"
        ),
        .by = ID
      )
    

    输出

       ID Year       Flag
    1   A 2019        Gap
    2   A 2021        Gap
    3   A 2022        Gap
    4   B 2019       Ap21
    5   B 2020       Ap21
    6   B 2021       Ap21
    7   C 2019       Ap22
    8   C 2020       Ap22
    9   C 2021       Ap22
    10  C 2022       Ap22
    11  D 2018 notupdated
    12  D 2019 notupdated
    
        2
  •  0
  •   Chris    2 年前

    我认为@jan的回答很好,这只是对这个问题的推理 而且更加复杂。

    library(cgwtools) # provides an rle for sequences, `seqle`, very handy...
    length(cgwtools::seqle(data$Year[which(data$ID == 'A')])$lengths)
    [1] 2 
    # any gap is a gap
    (cgwtools::seqle(data$Year[which(data$ID == 'B')])$values)+(cgwtools::seqle(data$Year[which(data$ID == 'B')])$lengths) -1
    [1] 2021
    (cgwtools::seqle(data$Year[which(data$ID == 'C')])$values)+(cgwtools::seqle(data$Year[which(data$ID == 'C')])$lengths) -1
    [1] 2022
    (cgwtools::seqle(data$Year[which(data$ID == 'D')])$values)+(cgwtools::seqle(data$Year[which(data$ID == 'D')])$lengths) -1
    [1] 2019
    # and use for Flag logic
    

    不 base 但是 seqle 可以派上用场。

        3
  •  0
  •   Andre Wildberg    2 年前

    如果规则应该独立运行,这里有一个替代方案。
    特别是规则” 存在于2020年或2021年(但不是两者都存在),然后输出“缺口” “需要的不仅仅是 any(c(2020, 2021) %in% Year)

    实例

    library(dplyr)
    
    data %>% 
      mutate(one = Year == 2020, two = Year == 2021, three = Year == 2022, 
             Flag = case_when(
                      (!any(one) | !any(two)) & (any(one) | any(two)) ~ "Gap"), 
             .by = ID) %>%
      select(-c(one, two, three))
       ID Year Flag
    1   A 2019  Gap
    2   A 2021  Gap
    3   A 2022  Gap
    4   B 2019 <NA>
    5   B 2020 <NA>
    6   B 2021 <NA>
    7   C 2019 <NA>
    8   C 2020 <NA>
    9   C 2021 <NA>
    10  C 2022 <NA>
    11  D 2018 <NA>
    12  D 2019 <NA>
    

    应用于所有规则

    library(dplyr)
    
    data %>% 
      mutate(one = Year == 2020, two = Year == 2021, three = Year == 2022, 
             Flag = case_when(
                      (!any(one) | !any(two)) & (any(one) | any(two)) ~ "Gap",
                      any(one) & any(two) & !any(three) ~ "Ap21", 
                      any(one) & any(two) & any(three) ~ "Ap22", 
                      !any(one) & !any(two) & !any(three) ~ "notupdated"), .by = ID) %>% 
      select(-c(one, two, three))
       ID Year       Flag
    1   A 2019        Gap
    2   A 2021        Gap
    3   A 2022        Gap
    4   B 2019       Ap21
    5   B 2020       Ap21
    6   B 2021       Ap21
    7   C 2019       Ap22
    8   C 2020       Ap22
    9   C 2021       Ap22
    10  C 2022       Ap22
    11  D 2018 notupdated
    12  D 2019 notupdated