R:重复值,直到新值按组出现为止,只有第一个非NA值出现一次

时间:2019-05-01 15:43:41

标签: r function text grouping repeat

我希望重复输入值,直到按组显示新值为止。我有一阵子的功能是在网上找到的,几乎可以满足我的需求,但不完全是。这是该功能:

    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

基本上,我不希望“重复”代码在找到第一个值之前就开始工作。在此之前,我希望各行保持不适用。目的是使行不会被错误分类,即,在上面的示例中,前两个A行不应标记为“纽约”。

3 个答案:

答案 0 :(得分:5)

按“组”分组后,一个选项是fill。将fill.direction一起使用,指定为“ up”或“ 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))

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

基本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