R function to determine if row in time series is differnt from previous and extract both rows from list

Viewed 33

I have a list of 14 individual organisms from a telemetry dataset tracking their movements. I'm interested in figuring out if they have crossed a few specific barriers at any point during the monitoring period. These 14 individuals are currently stored in a list and have detections ranging from 100's to 100,000's of detections.

An example to the dataset is below:

Date        Time      Individual      Location
2019-04-25  06:16:29  A69-1601-26907  DI 03
2019-04-25  06:23:31  A69-1601-26907  DI 03
2019-04-25  06:52:17  A69-1601-26907  BR 04
2019-04-25  07:41:31  A69-1601-26907  BR 04
2019-04-25  07:59:13  A69-1601-26907  BR 04
2019-04-25  08:16:19  A69-1601-26907  DI 03
2019-04-25  08:33:42  A69-1601-26907  DI 03

The goal would be to extract the two rows where the location has changed. For example, BR 04 and the one just before it (06:23:31 and 06:52:17 rows) and put them in their own dataframe. Then to also to extract the rows at 7:59:13 and 8:16:19 since it signifies that this individual crossed the barrier again. Doing this for the whole dataset for this individual. Eventually getting a dataframe of all the transits for that one individual.

Then to do that same function again for the other 13 individuals in the list. They can either be appended all to the same dataframe or be in their own in a list.

I've tried to use a for loop with ifelse statements, but it doesn't return anything.

Thanks!

3 Answers

Assuming you are okay with using the tidyverse, and assuming your data frame is called df:

library(tidyverse)

df %>%
  group_by(Individual) %>% 
  filter((Location != lag(Location)) | Location != lead(Location))

You can leave out the group_by line if you only have one Individual in your dataset.

Is this what you'd like to achieve:

 library(tidyverse)

df = data.frame(
    date = c("25.04.2019", "25.04.2019", "25.04.2019", "25.04.2019", "25.04.2019", "25.04.2019", "25.04.2019"),
    time = c("06:16:29", "06:23:31", "06:52:17", "07:41:31", "07:59:13", "08:16:19", "08:33:42"),
    location = c("DI 03", "DI 03", "BR 04", "BR 04", "BR 04", "DI 03", "DI 03")
)

df %>% filter(location != lag(location))

The filter(...) function compares each location with it's predecessor and keeps only those rows where there is a difference.

One way is to compare the current location with the next one (lead) and the previous one (lag), grouping on Individual, and look for records that are not the same in either.

library(dplyr)
df %>%
  group_by(Individual) %>%
  filter(Location!=lead(Location) | Location!=lag(Location)) 

# A tibble: 4 x 5
# Groups:   Individual [1]
  Date                 Individual     Location
  <chr>                <chr>          <chr>   
1 2019-04-25  06:23:31 A69-1601-26907 DI 03   
2 2019-04-25  06:52:17 A69-1601-26907 BR 04   
3 2019-04-25  07:59:13 A69-1601-26907 BR 04   
4 2019-04-25  08:16:19 A69-1601-26907 DI 03   

This should return one data frame containing the records of all individuals who changed location.


Data

df <- read.table(text="Date     Individual      Location
'2019-04-25  06:16:29'  A69-1601-26907  'DI 03'
'2019-04-25  06:23:31'  A69-1601-26907  'DI 03'
'2019-04-25  06:52:17'  A69-1601-26907  'BR 04'
'2019-04-25  07:41:31'  A69-1601-26907  'BR 04'
'2019-04-25  07:59:13'  A69-1601-26907  'BR 04'
'2019-04-25  08:16:19'  A69-1601-26907  'DI 03'
'2019-04-25  08:33:42'  A69-1601-26907  'DI 03'", header=TRUE, stringsAsFactors=FALSE)
Related