---
title: "Raincloud vignette"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Raincloud_vignette}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  #warning = FALSE, message = FALSE,
  comment = "#>"
)
```

```{r setup}
library(ggrain)
```

## The `geom_rain()` function
* handles as many rainclouds as you wish and can overlap them by a group
* connects within-subject observations longitudinally with lines using `id.long.var` argument
* colors dots by a covariate using the `cov` argument
* handles likert data by adding y-jittering with `likert = TRUE`
* changes orientation with `+ coord_flip()`

All individual elements of the plots can be edited, these are split into aesthetic and positioning arguments that are supplied by lists. For example the boxplots can be edited with `boxplot.args` and `boxplot.args.pos`, yet the others can also be edited by substituting for their name, i.e. `point/violin/line`. When you supply a list the defaults are overwritten so you may need to re-add them. To see the defaults run `?geom_rain`.

## Introduction

Here is our first plot which is just simply all the values of Sepal.Width in the iris dataset. For the function to work the value you want to plot **must be given to the y argument** in ggplot. You can then flip the plot with `+ coord_flip()` as we demonstrate below.

```{r most basic raincloud possible}
ggplot(iris, aes(1, Sepal.Width)) +
  geom_rain() +
  theme_classic() +
  theme(axis.title.x = element_blank(), 
        axis.text.x = element_blank(), axis.ticks.x = element_blank())
```

Let's see what is happening over the 3 Species of flowers. The fill must be a factor or a character vector!

```{r rainclouds by species grouped}
ggplot(iris, aes(1, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5) +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2')
```

Let's color the dots by Species, we do this by adding `color = Species` to ggplot. The default behavior of `geom_boxplot` is to color the lines in the boxplot showing the median and IQR. Therefore, we need to add a `boxplot.args` list to re-color the boxplot to black. When we do this all defaults are lost therefore we must add the options to not show outliers.

```{r rainclouds by Species colored}
ggplot(iris, aes(1, Sepal.Width, fill = Species, color = Species)) +
  geom_rain(alpha = .6,
            boxplot.args = list(color = "black", outlier.shape = NA)) +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2') +
  scale_color_brewer(palette = 'Dark2')
```
It is also possible to nudge the box plots so they are not overlapping with `boxplot.args.pos`. We will also flip them by setting the rain.side argument to left (i.e., `'l'`).
```{r rainclouds by Species colored dogded}
ggplot(iris, aes(1, Sepal.Width, fill = Species, color = Species)) +
  geom_rain(alpha = .5, rain.side = 'l',
            boxplot.args = list(color = "black", outlier.shape = NA),
            boxplot.args.pos = list(
              position = ggpp::position_dodgenudge(x = .1, width = 0.1), width = 0.1
            )) +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2') +
  scale_color_brewer(palette = 'Dark2') +
  guides(fill = 'none', color = 'none')
```

It could be even more useful to see the different species of flowers side by side rather than overlapping. The y value must be a factor or a character vector!

```{r rainclouds by species}
ggplot(iris, aes(Species, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5) +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2') +
  guides(fill = 'none', color = 'none')
```

We can flip the plots by adding `coord_flip()`.
```{r rainclouds by time flip}
ggplot(iris, aes(Species, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5) +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2') +
  guides(fill = 'none', color = 'none') +
  coord_flip()
```

This plot is a bit crammed, lets spread stuff out using the `boxplot.args.pos` & `violin.args.pos` arguments.
```{r rainclouds by time flip nudged}
ggplot(iris, aes(Species, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5, 
            boxplot.args.pos = list(
              width = 0.05, position = position_nudge(x = 0.13)),
            violin.args.pos = list(
              side = "r",
              width = 0.7, position = position_nudge(x = 0.2))) +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2') +
  guides(fill = 'none', color = 'none') +
  coord_flip()
```

Instead of coloring the dots by Species, the package offers the ability to color to another variable such as `Sepal.Length`. This will allow us to visualize how `Sepal.Width` and `Sepal.Length` relate to each other in each `Species` of flower.
We can do this by adding them as a covariate with the `cov` argument. At the current time the argument must be given as a string.
```{r rainclouds by time colored by group}
ggplot(iris, aes(Species, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .6,
            cov = "Sepal.Length") +
  theme_classic() +
  scale_fill_brewer(palette = 'Dark2') +
  guides(fill = 'none', color = 'none') +
  scale_color_viridis_c(option =  "A", direction = -1)
```

We will now take the species versicolor and virginica and make longitudinal data. We are going to see what fertilizer does to the Sepal.Width of both species!

```{r making long iris data}
set.seed(42) # the magic number

iris_subset <- iris[iris$Species %in% c('versicolor', 'virginica'),]

iris.long <- cbind(rbind(iris_subset, iris_subset, iris_subset), 
                   data.frame(time = c(rep("t1", dim(iris_subset)[1]), rep("t2", dim(iris_subset)[1]), rep("t3", dim(iris_subset)[1])),
                              id = c(rep(1:dim(iris_subset)[1]), rep(1:dim(iris_subset)[1]), rep(1:dim(iris_subset)[1]))))

# adding .5 and some noise to the versicolor species in t2
iris.long$Sepal.Width[iris.long$Species == 'versicolor' & iris.long$time == "t2"] <- iris.long$Sepal.Width[iris.long$Species == 'versicolor' & iris.long$time == "t2"] + .5 + rnorm(length(iris.long$Sepal.Width[iris.long$Species == 'versicolor' & iris.long$time == "t2"]), sd = .2)
# adding .8 and some noise to the versicolor species in t3
iris.long$Sepal.Width[iris.long$Species == 'versicolor' & iris.long$time == "t3"] <- iris.long$Sepal.Width[iris.long$Species == 'versicolor' & iris.long$time == "t3"] + .8 + rnorm(length(iris.long$Sepal.Width[iris.long$Species == 'versicolor' & iris.long$time == "t3"]), sd = .2)

# now we subtract -.2 and some noise to the virginica species
iris.long$Sepal.Width[iris.long$Species == 'virginica' & iris.long$time == "t2"] <- iris.long$Sepal.Width[iris.long$Species == 'virginica' & iris.long$time == "t2"] - .2 + rnorm(length(iris.long$Sepal.Width[iris.long$Species == 'virginica' & iris.long$time == "t2"]), sd = .2)

# now we subtract -.4 and some noise to the virginica species
iris.long$Sepal.Width[iris.long$Species == 'virginica' & iris.long$time == "t3"] <- iris.long$Sepal.Width[iris.long$Species == 'virginica' & iris.long$time == "t3"] - .4 + rnorm(length(iris.long$Sepal.Width[iris.long$Species == 'virginica' & iris.long$time == "t3"]), sd = .2)

iris.long$Sepal.Width <- round(iris.long$Sepal.Width, 1) # rounding Sepal.Width so t2 data is on the same resolution
iris.long$time <- factor(iris.long$time, levels = c('t1', 't2', 't3'))
```

Here we plot the species overlapping at each time point. We can see fertilizer caused the Sepal Width of the versicolor species to increase while the virginica species decreased slightly! 

```{r rainclouds by time by group}
ggplot(iris.long[iris.long$time %in% c('t1', 't2'),], aes(time, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5) +
  theme_classic() +
  scale_fill_manual(values=c("dodgerblue", "darkorange")) +
  guides(fill = 'none', color = 'none')
```

We can easily flank them using the `rain.side` argument for 2-by-2 flanking (i.e., `'f2x2'`). This also automatically uses `ggpp::position_dodgenudge` to dodge the boxplots. Yet, for descriptive purposes with will use the flanking argument `rain.side = 'f'` with the defaults from `'f2x2'`. The `rain.side = 'f'` argument defaults to a 2-by-2 yet throw a warning if you don't remap the `violin.args.pos`. When using flanking with more groups or more time points you must give specific `boxplot.args.pos` and `violin.args.pos` for each element. The left elements must have negative x-axis nudging values with the right ones have positive x-axis nudging values.

```{r rainclouds by time by group flipped}
ggplot(iris.long[iris.long$time %in% c('t1', 't2'),], aes(time, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5, rain.side = 'f',
             boxplot.args.pos = list(width = .1,
                position = ggpp::position_dodgenudge(width = .1, #width needed now in ggpp version 0.5.g
                  x = c(-.13, -.13, # pre versicolor, pre virginica
                        .13, .13))), # post; post
            violin.args.pos = list(width = .7,
             position = position_nudge(x = c(rep(-.2, 256*2), rep(-.2, 256*2),# pre; pre
                                             rep(.2, 256*2), rep(.2, 256*2))))) + #post; post
  theme_classic() +
  scale_fill_manual(values=c("dodgerblue", "darkorange")) +
  guides(fill = 'none', color = 'none')
```

We can connect each plant with lines using the `id.long.var` argument, we will also use the convient `rain.side = 'f2x2'`. As with the `cov` argument, it must be a string linking the ids of each observation across time.

```{r rainclouds by time by group flipped long id}
ggplot(iris.long[iris.long$time %in% c('t1', 't2'),], aes(time, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5, rain.side = 'f2x2', id.long.var = "id") +
  theme_classic() +
  scale_fill_manual(values=c("dodgerblue", "darkorange")) +
  guides(fill = 'none', color = 'none')
```

We can color the dots and the connecting lines by Species! We will also remove the lines around the violins by specifying their `color = NA`, yet we now must re-add the alpha argument.

```{r rainclouds by time by group flipped long id colored}
ggplot(iris.long[iris.long$time %in% c('t1', 't2'),], aes(time, Sepal.Width, fill = Species, color = Species)) +
  geom_rain(alpha = .5, rain.side = 'f2x2', id.long.var = "id",
            violin.args = list(color = NA, alpha = .7)) +
  theme_classic() +
  scale_fill_manual(values=c("dodgerblue", "darkorange")) +
  scale_color_manual(values=c("dodgerblue", "darkorange")) +
  guides(fill = 'none', color = 'none')
```

We can start to combine aspects, for example here is three timepoints with subjects connected, special flanking and a covariate mapped!

```{r rainclouds long cov}
ggplot(iris.long, aes(time, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5, rain.side = 'f', id.long.var = "id", cov = "Sepal.Length",
            boxplot.args = list(outlier.shape = NA, alpha = .8),
            violin.args = list(alpha = .8, color = NA),
            boxplot.args.pos = list(width = .1,
             position = ggpp::position_dodgenudge(width = .1,
                                                  x = c(-.13, -.13, # t1 old, t1 young
                                                        -.13, .13, 
                                                         .13, .13))),
            violin.args.pos = list(width = .7,
             position = position_nudge(x = c(rep(-.2, 256*2), rep(-.2, 256*2),# t1
                                             rep(-.2, 256*2), rep(.2, 256*2), # t2
                                             rep(.2, 256*2), rep(.2, 256*2))))) +
  theme_classic() +
  scale_fill_manual(values=c("dodgerblue", "darkorange")) +
  scale_color_viridis_c(option =  "A", direction = -1) +
  guides(fill = 'none', color = 'none')
```

Lastly, we can add a mean trend line using `stat_summary`. Accentuating the opposite effects fertilizers had on the two species of flowers!

```{r rainclouds by time by group flipped long id colored mean}
ggplot(iris.long[iris.long$time %in% c('t1', 't2'),], aes(time, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5, rain.side = 'f2x2') +
  theme_classic() +
  stat_summary(fun = mean, geom = "line", aes(group = Species, color = Species)) +
  stat_summary(fun = mean, geom = "point",
               aes(group = Species, color = Species)) +
  scale_fill_manual(values=c("dodgerblue", "darkorange")) +
  scale_color_manual(values=c("dodgerblue", "darkorange")) +
  guides(fill = 'none', color = 'none')
```

Here is some sample code on how to do a significance test on a 1-by-1 flanking raincloud with the package `ggsignif`. We will not run it as we don't want to add `ggsignif` as a package dependency.
```{r rainclouds sig, eval = F, echo = T}
ggplot(iris.long[iris.long$Species == 'versicolor' & iris.long$time %in% c('t1', 't2'),], aes(time, Sepal.Width, fill = Species)) +
  geom_rain(alpha = .5, rain.side = 'f1x1') +
 ggsignif::geom_signif(
  comparisons = list(c("t1", "t2")),
  map_signif_level = TRUE) +
scale_fill_manual(values=c("darkorange", "darkorange")) +
theme_classic()
```
![](https://raw.githubusercontent.com/njudd/ggrain/main/inst/git_pics/geom_signif_image.png)
