---
title: "Creating and Manipulating gtypes Objects"
author: "Eric Archer"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Creating and manipulating gtypes}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---
```{r echo = FALSE, message = FALSE}
library(strataG)
```

## Raw data

It is easiest to load raw genotype data from the disk if it is available as a text file, usually in comma-delimited (.csv) format. The standard R functions _read.table_ or _read.csv_ can be used to accomplish this. However, in _strataG_, the _readGenData_ function has been provided for .csv files, which is a wrapper for _read.csv_ that sets commonly used values for missing data and removes blank lines.

```{r}
gen.data <- readGenData("msats.csv")
str(gen.data)
```

For sequence data stored in FASTA format, the _read.fasta_ function is available, which is a wrapper for the _read.dna_ function in the _ape_ package with standard FASTA arguments set. This will create a DNAbin object in the workspace:

```{r}
fname <- system.file("extdata/dolph.seqs.fasta", package = "strataG")
x <- read.fasta(fname) 
x
```

For sequences stored in other formats, _read.dna_ should be used directly.

## Construction

For most functions in _strataG_, you will need to load your data into a _gtypes_ object. A _gtypes_ object is an R S4 class with several slots that are fully described in `?gtypes`.  
The easiest way to create a _gtypes_ object is with the _df2gtypes()_ function. This function assumes that you have a matrix or data.frame with columns for individual ids, stratification, and locus data. You then specify the columns in the data.frame where this information can be found. _df2gtypes()_ can be used for data with multiple alleles per locus, like this:
```{r}
# create a single data.frame with the msat data and stratification
msats.merge <- merge(dolph.strata, dolph.msats, all.y = TRUE, description = date())
str(msats.merge)

# create the gtypes object
msats.fine <- df2gtypes(msats.merge, ploidy = 2, id.col = 1, strata.col = 3, loc.col = 5)
```

...or for haploid data, like this:
```{r}
data(dolph.seqs)

seq.df <- dolph.strata[ c("id", "broad", "id")]
colnames(seq.df)[3] <- "D-loop"
dl.g <- df2gtypes(seq.df, ploidy = 1, sequences = dolph.seqs)
dl.g
```

Note that since each sequence in _dolph.seqs_ is for a given individual, the _num.ind_ and _num.haplotypes_ values are the same for both strata. In order to convert the sequences to unique haplotypes, use the _labelHaplotypes()_ function:

```{r}
dl.haps <- labelHaplotypes(dl.g)
dl.haps
```

### _sequence2gtypes_ - Convert DNA sequences

The _sequence2gtypes()_ function creates an unstratified _gtype_ object with just a set of DNA sequences:
```{r}
data(dolph.haps)

haps.g <- sequence2gtypes(dolph.haps)
haps.g
```

If you have a vector that identifies strata designations for the sequences, that can be supplied as well:
```{r}
# extract and name the stratification scheme
strata <- dolph.strata$fine
names(strata) <- dolph.strata$ids

# create the gtypes object
dloop.fine <- sequence2gtypes(dolph.seqs, strata, seq.names = "dLoop",
  description = "dLoop: fine-scale stratification")
dloop.fine
```

Note that stratification is generally provided for individuals, thus if you want to stratify the resulting _gtypes_ object from _sequence2gtypes()_, one sequence for each individual should be provided, rather than just a set of unique haplotypes.

### Conversions from other packages.

THere are conversion functions for data objects from several other popular packages in R, such as _adegenet_(genind), _pegas_(loci), and _phangorn_(phydat).
```{r}
library(adegenet)
# from example(df2genind)
df <- data.frame(locusA=c("11","11","12","32"),
                 locusB=c(NA,"34","55","15"),
                 locusC=c("22","22","21","22"))
row.names(df) <- .genlab("genotype",4)
obj <- df2genind(df, ploidy=2, ncode=1)
obj

# convert to gtypes
gi.g <- genind2gtypes(obj)
gi.g
```

## Accessor functions

There are several functions for getting basic information from a _gtypes_ object (see `?accessors`):

* __getNumInd(g)__ The number of individuals.
* __getNumLoci(g)__ The number of loci.
* __getNumStrata(g)__ The number of strata in the current scheme.
* __getIndNames(g)__ The names of the individuals.
* __getLociNames(g)__ The names of the loci or genes.
* __getStrataNames(g)__ The names of the strata in the current scheme.
* __getPloidy(g)__ The ploidy of each locus.
* __getStrata(g)__ The current strata to which each individual belongs.
* __getSchemes(g)__ A data frame of potential stratification schemes.
* __getSequences(g)__ The sequences stored in a haploid object.
* __getDescription(g)__ The text description of the object.
* __getOther(g)__ The list used to store other information about the object.


Some functions are available for modifying values in the object as well, such as:

* __setStrata(g)__ Replace the vector of strata assignments.
* __setSchemes(g)__ Replace the data.frame of potential stratification schemes.
* __setDescription(g)__ Replace the label describing the object.
* __setOther(g)__ Replace the optional data stored in the \@other slot.

## Subsetting/Indexing

A _gtypes_ object can be subset using the standard R '[' indexing operation, with three slots: [i, j, k]. The first (i) specifies the desired individuals, the second (j) is the loci to return, and the third (k) is the strata. All standard R indexing operations involving numerical, character, or logical vectors work for each argument.
For example, to return 10 random individuals:
```{r}
sub.msats <- msats.fine[sample(getNumInd(msats.fine), 10), , ]
sub.msats
```

...or to return specific loci:
```{r}
sub.msats <- sub.msats[, c("D11t", "EV37", "TV7"), ]
sub.msats
```

...or some loci in a specific stratum:
```{r}
sub.msats <- msats.fine[, c("Ttr11", "D11t"), "Coastal"]
sub.msats
```

## Summary

Several functions have been defined for _gtypes_, that provide summaries for individuals (`summarizeInds()`), loci (`summarizeLoci()`), and sequences (`summarizeSeqs()`):
```{r}
summarizeLoci(msats.fine)
summarizeInds(msats.fine)
```


## Stratifying samples

You can specify the stratification scheme when creating a _gtypes_ object as in the examples above. Once a _gtypes_ object has been created, you can also change the stratification scheme by either supplying a new vector for the \@strata slot:
```{r}
# randomly stratify individuals to two populations
msats <- msats.g
new.strata <- sample(c("Pop1", "Pop2"), getNumInd(msats), rep = TRUE)
names(new.strata) <- getIndNames(msats)
setStrata(msats) <- new.strata
msats
```

or, if there is a stratification scheme data.frame in the \@schemes slot, you can use the _stratify_ function to choose a stratification scheme:
```{r}
# choose "broad" stratification scheme
msats <- stratify(msats, "broad")
msats
```

You can update the \@schemes slot with data.frame like this:
```{r}
new.schemes <- getSchemes(msats)
new.schemes$ran.pop <- sample(c("Pop5", "Pop6"), getNumInd(msats), rep = TRUE)
setSchemes(msats) <- new.schemes
```

NOTE: Filling or changing the \@schemes slot does not affect the current stratification of the samples. You must then select a new stratification scheme or fill the \@strata slot as above.
```{r}
stratify(msats, "ran.pop")
```

If some samples should be unstratified (excluded from any stratified analyses), they should have NAs in the appropriate position in the \@strata slot. For example:
```{r}
# unstratify a random 10 samples
x <- getStrata(msats)
x[sample(getIndNames(msats), 10)] <- NA
msats
```

You can also randomly permute the current stratification scheme using the _permuteStrata()_ function like this:
```{r}
msats <- stratify(msats, "fine")

# original
msats

# permuted
ran.msats <- permuteStrata(msats)
ran.msats
```
NOTE: Only samples assigned to strata are permuted with _permuteStrata_. Those not assigned (NAs) remain unassigned.

## Exporting

The allelic data in a _gtypes_ object can be converted back to a matrix or data frame with _as.matrix()_ and _as.data.frame()_:
```{r}
gen.mat <- as.matrix(msats)
head(gen.mat)
```

By default, this function splits each allele into its own column. One can make a matrix with one locus per column and alleles separated by a specified character by setting the _one.col_ argument to _TRUE_:
```{r}
gen.mat <- as.matrix(msats, one.col = TRUE)
head(gen.mat)
```

The contents of a _gtypes_ object can be written to a file with the _writeGtypes()_ function. This will write a .csv file with the allelic information and a .fasta file for any sequence data if it exists.
