Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Fill first (only one) NA with next non-NA value by group using dplyr/tidyr

I hava a problem, where I need to fill NA by group, but only one (the first) NA before some non-NA value (direction = "up"). I know the tidyr fill() function but do not know how to use it conditionally (so to fill only one NA above some non-NA value).

df <- data.frame(g=c(1,1,1,1,1,1, 2,2,2,2,2,2,2),v=c(NA,NA,5,NA,8,NA, 1,1,NA,2,NA,NA,3))

Data (with group "g" and values "v"):

   g  v
1  1 NA
2  1 NA
3  1  5
4  1 NA
5  1  8
6  1 NA
7  2  1
8  2  1
9  2 NA
10 2  2
11 2 NA
12 2 NA
13 2  3

should become…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

   g  v
1  1 NA
2  1  5
3  1  5
4  1  8
5  1  8
6  1 NA
7  2  1
8  2  1
9  2  2
10 2  2
11 2 NA
12 2  3
13 2  3

>Solution :

You can always create your own solution:

fill_one_up <- \(x) {
  n <- length(x)
  if (n <= 1L) return(x)
  for (i in 2L:n) {
    if (!is.na(x[i]) && is.na(x[i-1L])) {
      x[i-1L] <- x[i]
    }
  }
  return(x)
}

df <- df |> mutate(v2 = fill_one_up(v), .by=g)

#    g  v v2
# 1  1 NA NA
# 2  1 NA  5
# 3  1  5  5
# 4  1 NA  8
# 5  1  8  8
# 6  1 NA NA
# 7  2  1  1
# 8  2  1  1
# 9  2 NA  2
# 10 2  2  2
# 11 2 NA NA
# 12 2 NA  3
# 13 2  3  3

If you need more speed you can translate the logic to Rcpp:

Rcpp::cppFunction("NumericVector fill_one_up_cpp(NumericVector x) {
  int n = x.size();
  if (n <= 1) return x;
  for (int i = 1; i < n; i++) {
    if (!NumericVector::is_na(x[i]) && NumericVector::is_na(x[i-1])) {
      x[i-1] = x[i];
    }
  }
  return x;
}")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading