Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove trailing NA by group in a data.frame

I have a data.frame with a grouping variable, and some NAs in the value column.

df = data.frame(group=c(1,1,2,2,2,2,2,3,3), value1=1:9, value2=c(NA,4,9,6,2,NA,NA,1,NA))

I can use zoo::na.trim to remove NA at the end of a column: this will remove the last line of the data.frame:

library(zoo)
library(dplyr)
df %>% na.trim(sides="right")

Now I want to remove the trailing NAs by group; how can I achieve this using dplyr?

Expected output for value2 column: c(NA, 4,9,6,2,1)

like image 340
agenis Avatar asked Feb 13 '19 10:02

agenis


1 Answers

You could write a little helper function that checks for trailing NAs of a vector and then use group_by and filter.

f <- function(x) { rev(cumsum(!is.na(rev(x)))) != 0 }

library(dplyr)
df %>% 
  group_by(group) %>% 
  filter(f(value2))
# A tibble: 6 x 3
# Groups:   group [3]
  group value1 value2
  <dbl>  <int>  <dbl>
1     1      1     NA
2     1      2      4
3     2      3      9
4     2      4      6
5     2      5      2
6     3      8      1

edit

If we need to remove both leading and trailing zero we need to extend that function a bit.

f1 <- function(x) { cumsum(!is.na(x)) != 0 & rev(cumsum(!is.na(rev(x)))) != 0 }

Given df1

df1 = data.frame(group=c(1,1,2,2,2,2,2,3,3), value1=1:9, value2=c(NA,4,9,NA,2,NA,NA,1,NA))
df1
#  group value1 value2
#1     1      1     NA
#2     1      2      4
#3     2      3      9
#4     2      4     NA
#5     2      5      2
#6     2      6     NA
#7     2      7     NA
#8     3      8      1
#9     3      9     NA

We get this result

df1 %>% 
  group_by(group) %>% 
  filter(f1(value2))
# A tibble: 5 x 3
# Groups:   group [3]
  group value1 value2
  <dbl>  <int>  <dbl>
1     1      2      4
2     2      3      9
3     2      4     NA
4     2      5      2
5     3      8      1
like image 122
markus Avatar answered Sep 22 '22 10:09

markus