---
title: "4. Fantastic Groups and how to use them"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{4. Fantastic Groups and how to use them}
  %\VignetteEncoding{UTF-8}
  %\VignetteEngine{knitr::rmarkdown}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
    echo = TRUE,
    fig.width = 6,
    fig.asp = 0.7
)

```


Groupings are a big emphasis in `sftrack`. Structurally they are built with in the same vein as `sfc` and `sfg` classes in `sf`. 

To begin an `s_group` is a singular grouping. Its whats stored at the row level. 
A `c_grouping` is a collection of `s_groups` and exists at the column level. Groups also have an `active_group` argument, which turns on and off certain groups for analysis and plotting purposes.

We start by looking at the structure of a `c_grouping`

```{r}
library("sftrack")
data('raccoon', package = 'sftrack')
#raccoon <- read.csv(system.file('extdata/raccoon_data.csv', package='sftrack'))
group_list = list(id = raccoon$animal_id, month = as.POSIXlt(raccoon$timestamp)$mon+1)

cg1 <- make_c_grouping(x=group_list, active_group=c('id','month'))
str(cg1)
cg1[[1]]
```

A grouping contains group related information. The `id` of the subject/sensor is the lowest level of grouping for the data. Any additional grouping variables are optional. 

A c_grouping is simply a collection of `s_group`s. The `s_group` is where the grouping data is stored, and can be modified at the row level. The `s_groups` main job is to store row level grouping information and maintain consistency of the grouping variables.


## Single groups (s_group) 
An s_group is the grouping variables for a single row of data.  

You can make an `s_group` object using `make_s_group()`, and giving it a list with the group variables named. In this example we have a single sensor named 'TTP_058' from a raccoon, and an additional grouping variable of month (entered as its numeric interpretation).

All grouping information is converted and stored as a character in the s_group.

```{r}

singlegroup <- make_s_group(list(id='TTP_058', month = 4))
str(singlegroup)
```

Because `s_group`s are simply lists, you can edit individual elements in an s_group
```{r}
singlegroup 
singlegroup[1] <- 'CJ15'
singlegroup$month <- '5'
str(singlegroup)
```


## Column groupings (c_grouping) 

C_groupings are a collection of s_groups with the same grouping names and an 'active_group' which is a subset of all the available group names.

Similarly to s_group you can make a c_grouping with `make_s_group`. The argument `x` takes a list where each element is a vector indicating the named groupings as well as a vector of the active groups.

```{r}
group_list <- list(id = rep(1:2,10), year = rep(2020, 10))
cg <- make_c_grouping(x=group_list, active_group=c('id','year'))
str(cg)
```

You can also make a c_grouping by concatenating multiple s_groups. All `s_groups` must have the same names or an error is returned.

```{r}
a <- make_s_group(list(id = 1, year = 2020))
b <- make_s_group(list(id = 1, year = 2021))
c <- make_s_group(list(id = 2, year = 2020))
cg <- c(a, b , c)

summary(cg)
```
You'll notice sftrack warns if any grouping combination only has one relocation. This may be relevant for different kinds of analysis where you need more than one point to consider a movement. 

You can also combine c_grouping together with `c()`. All names and active_groups must be the same.  

```{r}
cg_combine <- c(cg,cg)
summary(cg_combine)
```
You can also edit groupings like a list, but you must replace it with an s_group object.
```{r}
cg[1]
cg[1] <- make_s_group(list(id=3,year=2019))
cg[1]

```

And the group names must match the ones in the c_grouping or an error is returned
```{r}
# Try to add an s_group with a month field when the original group had year instead 
try( cg[1] <- make_s_group(list(id=3,month=2019)) )
```


## Selecting a grouping

As `c_groupings` are stored as lists, it can be difficult to refer to a single group or combination of groupings. This is where the sort_index can come in handy. The sort_index is a factor of the combined active_group variables for each row where paste(id, name1,name2,...,sep='_')). The sort index is remade every time the active group changes, and therefore can be used to subset. You can access the sort index using `group_labels()`. 

```{r}
group_list <- list(id = rep(1:2,10), year = rep(2020, 10))
cg <- make_c_grouping(x=group_list, active_group=c('id','year'))
group_labels(cg)[1:10]

# Subsetting a particular sensor from our raccoon data

data('raccoon', package = 'sftrack')
raccoon$month <- as.POSIXlt(raccoon$timestamp)$mon+1

raccoon$time <- as.POSIXct(raccoon$timestamp, tz='EST')
coords = c('longitude','latitude')
group = list(id = raccoon$animal_id, month = as.POSIXlt(raccoon$timestamp)$mon+1)
time = 'time'

my_sftraj <- as_sftraj(data = raccoon, coords = coords, group = group, time = time)
head(my_sftraj[group_labels(my_sftraj) %in% c('TTP-058_1'), ])


```

You can also subset by entering the group label of the group itself in either the c_grouping or the sftrack/sftraj object:

```{r}
head(cg['1_2020'])

sub <- my_sftraj['TTP-058_1',]
print(sub,5, 3)
```

You can refer to the levels of the sort index using `group_names`, this returns levels() of the sort index.

```{r}
group_names(cg)
```


## Active group 

The active_group is a simple yet powerful feature. It dictates how your data is grouped for essentially all calculations. It can also be changed on the fly. You can view and change the active group of a column grouping with `active_group()`. Once changed, it recalculates the sort_index and in some cases recalculates the geometries.

Active groups can be changed for any sftrack/straj/c_grouping

```{r}
# sftrack
active_group(my_sftraj)
summary(my_sftraj, stats = T)

# change the active group to id only
active_group(my_sftraj) <- c('id')
active_group(my_sftraj)

summary(my_sftraj, stats = T)

# column groupings work the same way
active_group(cg)
active_group(cg) <- 'id'
active_group(cg)

```
