Can tidyr `fill()` be used with if_else() in R?

Viewed 901
library(tidyverse)
df <- tibble(col1 = c("a", "a", "b", "b", "c", "c"),
             col2 = c(2, NA, 5, NA, 7, NA))
#> # A tibble: 6 x 2
#>   col1   col2
#>   <chr> <dbl>
#> 1 a         2
#> 2 a        NA
#> 3 b         5
#> 4 b        NA
#> 5 c         7
#> 6 c        NA

Let's start with the data frame above. I want to fill down on col2, unless the value in col1 is a. The solution would look like this:

#> # A tibble: 6 x 2
#>   col1   col2  col3
#>   <chr> <dbl> <dbl>
#> 1 a         2     2
#> 2 a        NA    NA
#> 3 b         5     5
#> 4 b        NA     5
#> 5 c         7     7
#> 6 c        NA     7

My attempt below is not working. How do I get tidyr::fill() to work in this if_else() context?

df %>% mutate(col3 = if_else(col1 != "a", fill(col2), col2))
#> Error in UseMethod("fill_") : no applicable method for 'fill_' 
#> applied to an object of class "c('double', 'numeric')"
1 Answers

I don't think this is a behavior supported by the function. Instead, you can do:

df %>%
 filter(col1 == "a") %>%
 bind_rows(df %>%
            filter(col1 != "a") %>%
            fill(col2))

  col1   col2
  <chr> <dbl>
1 a         2
2 a        NA
3 b         5
4 b         5
5 c         7
6 c         7

Or if you actually need col3, then you can use na.locf() from zoo:

df %>%
 mutate(col3 = ifelse(col1 != "a", na.locf(col2), col2))

  col1   col2  col3
  <chr> <dbl> <dbl>
1 a         2     2
2 a        NA    NA
3 b         5     5
4 b        NA     5
5 c         7     7
6 c        NA     7
Related