【问题标题】:R: Repeat value until new value appears by group, only once first non-NA value appearsR:重复值直到按组出现新值,仅出现第一个非NA值
【发布时间】:2019-05-01 15:43:40
【问题描述】:

我希望重复值,直到按组出现新值。我有一个不久前在网上找到的功能,它几乎可以满足我的要求,但并不完全。这是那个函数:

    repeat.before <- function(x) {
  ind <- which(!is.na(x))
  ind_rep <- ind
  if (is.na(x[1])) {
    ind_rep <- c(min(ind), ind)
    ind <- c(1, ind)
  }
  rep(x[ind_rep], times = diff(c(ind, length(x) + 1)))
}

此函数将成功地重复该值,直到出现一个新值,按组。问题是,如果列以 NA 开头,则在第一个值之前存在的以下行最终将采用第一个值,而不是剩余的 NA。我将用这个例子来说明我的意思:

    group    location 
    A        NA
    A        NA
    A        New York
    A        NA
    A        NA
    B        Chicago
    B        NA
    B        Philly
    B        NA

上面的代码会输出这个:

    group    location 
    A        New York
    A        New York
    A        New York
    A        New York
    A        New York
    B        Chicago
    B        Chicago
    B        Philly
    B        Philly

同样,这与我正在寻找的非常接近,但不完全是。这是我正在寻找的输出:

    group    location 
    A        NA
    A        NA
    A        New York
    A        New York
    A        New York
    B        Chicago
    B        Chicago
    B        Philly
    B        Philly

基本上,我不希望“重复”代码在找到第一个值之前开始工作。在它这样做之前,我希望这些行保持 NA。目的是避免对行进行错误分类,即在上面的示例中,前两行 A 不应标记为 New York。

【问题讨论】:

    标签: r function text grouping repeat


    【解决方案1】:

    一个选项是 fill 在按“组”分组后。使用 fill.direction 指定为“向上”或“向下”(默认选项)。在这里,我们只需要基于预期输出的 'down' 选项

    library(dplyr)
    library(tidyr)
    df1 %>%
      group_by(group) %>%
      fill(location) 
    # A tibble: 9 x 2
    # Groups:   group [2]
    #  group location
    #  <chr> <chr>   
    #1 A     <NA>
    #2 A     <NA>
    #3 A     New York
    #4 A     New York
    #5 A     New York
    #6 B     Chicago 
    #7 B     Chicago 
    #8 B     Philly  
    #9 B     Philly  
    

    数据

    df1 <- structure(list(group = c("A", "A", "A", "A", "A", "B", "B", "B", 
     "B"), location = c(NA, NA, "New York", NA, NA, "Chicago", NA, 
     "Philly", NA)), class = "data.frame", row.names = c(NA, -9L))
    

    【讨论】:

    • 我对 dplyr 不太熟悉,因为我只在这里和那里使用过它。如果我想将结果分配给一个新列,例如“location_2”,我将如何使用这种方法来做到这一点?顺便感谢您的快速回复!编辑:我相信这是 tidyr,而不是 dplyr?
    • @Jared 不希望前两行填充“纽约”。我会省略填充的行。
    • @JaredAnnibale 这很简单, df1 %&gt;% mutate(location2 = location) %&gt;% group_by(group %&gt;% fill(location2)
    • @CTHall 是的-如果您将方向更改为“向下”,它会完美运行。谢谢你们!
    【解决方案2】:

    您还可以通过 na.locf 函数使用 zoo 包。

    library(zoo)
    df1 <-
      structure(list(
        group = c("A", "A", "A", "A", "A", "B", "B", "B",
                  "B"),
        location = c(NA, NA, "New York", NA, NA, "Chicago", NA,
                     "Philly", NA)
      ),
      class = "data.frame",
      row.names = c(NA,-9L))
    
    df1$location2 <- na.locf(df1$location, na.rm = F)
    df1
    
      group location location2
    1     A     <NA>      <NA>
    2     A     <NA>      <NA>
    3     A New York  New York
    4     A     <NA>  New York
    5     A     <NA>  New York
    6     B  Chicago   Chicago
    7     B     <NA>   Chicago
    8     B   Philly    Philly
    9     B     <NA>    Philly
    

    【讨论】:

      【解决方案3】:

      基础R

      transform(df1,
                loc2 = ave(df1$location,
                           cumsum(!is.na(df1$location)),
                           FUN = function(x) x[1]))
      #  group location     loc2
      #1     A     <NA>     <NA>
      #2     A     <NA>     <NA>
      #3     A New York New York
      #4     A     <NA> New York
      #5     A     <NA> New York
      #6     B  Chicago  Chicago
      #7     B     <NA>  Chicago
      #8     B   Philly   Philly
      #9     B     <NA>   Philly
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-27
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 2017-11-01
        • 2014-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多