Molly Westbrook
Molly Westbrook

Reputation: 142

R filtering the first point before and the last point after a section of rows containing NA

Working with tracking data that tracks the XY position of an object. Reproducible example of my data:

trial <- c(rep(1, 25), rep(2, 25), rep(3, 25))
timemini <- c(1:25)
time <- c(rep(timemini, 3))
Y <- c(NA, NA, 3:10, NA, NA, NA, NA, NA, 16:25, NA, NA, NA, 48:55, NA, NA, NA, NA, NA, NA, NA, NA, 64:69, NA, 36:37, NA, 39:40, NA, 42:45, NA, NA, NA, NA, NA, 51:59)
example <- as.data.frame(cbind(trial, time, Y))

I am interested in filtering the NA's, as well as the first point before and the last point after each period of NA, reglardless of how long the period of NA is (as short as one point, or sometimes as long as 100 or so).

I can filter out the NA themselves no problem with the following code:

NA.from.example <- example %>%
  filter(is.na(Y))

Was trying to accomplish this with something from this question but the best I could do was this, which only filters out the first instance of each NA (which is the first point of every trial, as the tracker needs a few frames of movement before it can find the object.

NAsandwich <- example %>%
  group_by(trial) %>%
  slice(max(1, match(TRUE, is.na(Y)) - 5):match(TRUE, is.na(Y)))

Any help would be appreciated! I usually use dplyr but any solution that works is ok with me.

EDIT

This is what I'm looking for in terms of expected output:

subset <- example[c(1:3, 10:16, 26:29, 36:45, 51:52, 53:55, 56:58, 61:67),]

Each trial always begins with NA, so I don't need the point before, but I usually run my code with a group_by(trial) in my pipelines. I don't know if that's applicable here.

Upvotes: 1

Views: 122

Answers (2)

akrun
akrun

Reputation: 886948

Here is an option with rleid

library(dplyr)
library(data.table)
example %>%
     group_by(trial) %>% 
     group_by(grp = rleid(!is.na(Y)), .add = TRUE) %>% 
     filter(all(is.na(Y))| row_number() %in% c(1, n()))  %>%
     ungroup

Upvotes: 1

hachiko
hachiko

Reputation: 747

Would this work?

example2 <- example %>%
  mutate(next_one = lead(Y),
         previous_one = lag(Y))

example2_filter <- example2 %>%
  filter(is.na(Y) | is.na(next_one) | is.na(previous_one)) 

Upvotes: 0

Related Questions