Search code examples
rdplyr

dplyr::first() to choose first non NA value


I am looking for a way to extract the first and last non-NA value from each group. I am using dplyr::first() and dplyr::last(), but I can´t work out how to choose the first or last non-NA value.

library(dplyr)
set.seed(123)
d <- data.frame(
  group = rep(1:3, each = 3),
  year = rep(seq(2000,2002,1),3),
  value = sample(1:9, r = T))

#Introduce NA values in first row of group 2 and last row of group 3
d %>%
  mutate(
    value = case_when(
      group == 2 & year ==2000 ~ NA_integer_,
      group == 3 & year ==2002 ~ NA_integer_,
      TRUE ~ value))%>%
  group_by(group) %>% 
  mutate(
    first = dplyr::first(value),
    last = dplyr::last(value))

RESULT (with issue)

# A tibble: 9 x 5
# Groups:   group [3]
  group  year value first  last
  <int> <dbl> <int> <int> <int>
1     1  2000     3     3     4
2     1  2001     8     3     4
3     1  2002     4     3     4
4     2  2000    NA    NA     1
5     2  2001     9    NA     1
6     2  2002     1    NA     1
7     3  2000     5     5    NA
8     3  2001     9     5    NA
9     3  2002    NA     5    NA

Can you help me make the values in the "first" column for group 2 = 9 and the values in the "last" column from group 3 = 9?

I very much prefer a tidyverse solution if one such exists?


Solution

  • Use na.omit, compare:

    first(c(NA, 11, 22))
    # [1] NA
    
    first(na.omit(c(NA, 11, 22)))
    # [1] 11
    

    Using example data:

    d %>%
      mutate(
        value = case_when(
          group == 2 & year ==2000 ~ NA_integer_,
          group == 3 & year ==2002 ~ NA_integer_,
          TRUE ~ value))%>%
      group_by(group) %>% 
      mutate(
        first = dplyr::first(na.omit(value)),
        last = dplyr::last(na.omit(value)))
    
    # # A tibble: 9 x 5
    # # Groups:   group [3]
    #   group  year value first  last
    #   <int> <dbl> <int> <int> <int>
    # 1     1  2000     3     3     4
    # 2     1  2001     8     3     4
    # 3     1  2002     4     3     4
    # 4     2  2000    NA     9     1
    # 5     2  2001     9     9     1
    # 6     2  2002     1     9     1
    # 7     3  2000     5     5     9
    # 8     3  2001     9     5     9
    # 9     3  2002    NA     5     9