![](../hanze/hanze.png)

---

[Go back to the main page](../index.html)  
[Go back to the R overview page](../R/R_01_index.html)  

---

```{r setup, include=FALSE} 
knitr::opts_chunk$set(warning = FALSE, message = FALSE) 
```

This Rmd file can be downloaded [here](./R_00_tidy_overview.Rmd)

```{r}
library(tidyverse)
```


# 📘 Tidyverse Overview

💡 *This page provides a structured overview of core tidyverse functions.  
Click a category to expand and jump to detailed examples.*

The examples shown are performed on the Puromycin dataset. The Puromycin dataset is a classic example dataset built into the base R installation (within the datasets package). It originates from a biochemical experiment and is widely used for demonstrating and testing nonlinear regression models, particularly the Michaelis-Menten kinetics model in enzyme reactions.

```{r}
head(Puromycin)
```


---

## Summary Table

💡 *This section summarizes the core Tidyverse operations on tibbles. Click on the triangles to expand.*

<details>
<summary><strong>🧩 Row Operations</strong> — `drop_na()`, `filter()`, `slice()`, `arrange()`, `distinct()`, `slice_sample()`, `slice_min()`, `slice_max`</summary>

Select, subset, or reorder rows.  
➡️ [See Row Actions ↓](#row-operations)
</details>

<details>
<summary><strong>📊 Column Operations</strong> — `select()`, `rename()`, `mutate()`, `transmute()`, `relocate()`, `across()`</summary>

Choose, rename, or transform columns.  
➡️ [See Column Actions ↓](#column-operations)
</details>

<details>
<summary><strong>🧮 Grouping & Aggregation</strong> — `group_by()`, `ungroup()`, `summarize()`, `mutate()`, `filter()`</summary>

Split data into groups and compute summaries.  
➡️ [See Group Actions ↓](#grouping)
</details>

<details>
<summary><strong>🔗 Joins & Binding</strong> — `left_join()`, `inner_join()`, `bind_rows()`</summary>

Combine multiple data frames.  
➡️ [See Join Actions ↓](#joins)
</details>

<details>
<summary><strong>🔄 Reshaping Data</strong> — `pivot_longer()`, `pivot_wider()`</summary>

Restructure data between long and wide formats.  
➡️ [See Reshaping ↓](#reshaping)
</details>

<details>
<summary><strong>📈 Visualization</strong> — `ggplot()`, `geom_*()`</summary>

Create and customize plots.  
➡️ [See Visualization ↓](#visualization)
</details>

<details>
<summary><strong>🧰 Utilities</strong> — `glimpse()`, `pull()`, `count()`</summary>

Inspect or extract data quickly.  
➡️ [See Utilities ↓](#utilities)
</details>

---


# Function-Specific Actions with Examples

---

## 🧩 Actions on Rows {#row-operations}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section lists core row operations in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>drop_na()</strong> – Drop rows containing `NA` values</summary>

First create a copy with an `NA` value: 

```{r}
Puro_with_NA <- as.tibble(Puromycin) # create a copy
Puro_with_NA[1, 2] <- NA # replace row 1, column 2 with NA
Puro_with_NA
```

And drop the row with the NA:  

```{r}
# Drop row with NA
Puro_with_NA %>% drop_na() 
```


</details>

<details>
<summary><strong>filter()</strong> – Subset rows based on conditions</summary>

```{r}
# Keep only rows where rate > 200
Puromycin %>% filter(rate > 200)
```

Selects rows that meet logical conditions. Supports multiple conditions with `&` (and) or `|` (or).  
</details>

<details>
<summary><strong>slice()</strong> – Select rows by position</summary>

```{r}
# Keep the first 5 rows
Puromycin %>% slice(1:5)
```

Select rows by numeric positions or helpers like `slice_head()` or `slice_tail()`.  
</details>

<details>
<summary><strong>arrange()</strong> – Reorder rows by variable(s)</summary>

```{r}
# Sort by rate descending
Puromycin %>% arrange(desc(rate))
```

Orders rows by one or more columns. Use `desc()` for descending order.  
</details>

<details>
<summary><strong>distinct()</strong> – Keep unique rows</summary>

```{r}
# Keep unique values of rate
Puromycin %>% distinct(rate)
```

Removes duplicate rows based on one or more columns.  
</details>

<details>
<summary><strong>slice_sample()</strong> – Random sample of rows</summary>

```{r}
# Randomly sample 3 rows
Puromycin %>% slice_sample(n = 3)
```

Randomly selects rows; can sample fractionally with `prop`.  
</details>

<details>
<summary><strong>slice_min()/slice_max()</strong> – Top or bottom rows by value</summary>

```{r}
# 3 rows with highest rate
Puromycin %>% slice_max(rate, n = 3)
```

Select rows with minimum or maximum values of a variable.  
</details>

---

## 📊 Actions on Columns {#column-operations}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section lists core column operations in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>select()</strong> – Choose specific columns</summary>

```{r}
# Select columns conc and rate
Puromycin %>% select(conc, rate)
```

Keeps only the specified columns. Can use helper functions like `starts_with()`, `ends_with()`, or `contains()`.  
</details>

<details>
<summary><strong>rename()</strong> – Rename columns</summary>

```{r}
# Rename conc to conc_ppm
Puromycin %>% rename(conc_ppm = conc)
```

Changes column names without altering the data.  
</details>

<details>
<summary><strong>mutate()</strong> – Add or modify columns</summary>

```{r}
# Add a new column rate_per_conc
Puromycin %>% mutate(rate_per_conc = rate / conc)
```

Creates new columns or modifies existing ones using expressions.  
</details>

<details>
<summary><strong>transmute()</strong> – Create new columns and drop others</summary>

```{r}
# Keep only rate_per_conc column
Puromycin %>% transmute(rate_per_conc = rate / conc)
```

Generates new columns and drops all others in the output.  
</details>

<details>
<summary><strong>relocate()</strong> – Move columns to new positions</summary>

```{r}
# Move state column to the first position
Puromycin %>% relocate(state, .before = 1)
```

Reorders columns without changing data.  
</details>

<details>
<summary><strong>across()</strong> – Apply functions to multiple columns</summary>

```{r}
# Convert all numeric columns to log scale
Puromycin %>% mutate(across(where(is.numeric), log))
```

Applies a function across selected columns, often used inside `mutate()` or `summarize()`.  
</details>

---

## 🧮 Actions on Groups {#grouping}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section lists core grouping operations in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>group_by()</strong> – Group data by one or more variables</summary>

```{r}
# Group by conc
Puromycin %>% group_by(conc)
```

Creates groups in the data for subsequent summarization or manipulation.  
</details>

<details>
<summary><strong>ungroup()</strong> – Remove grouping</summary>

```{r}
# Remove grouping
Puromycin %>% group_by(conc) %>% ungroup()
```

Removes existing groups, returning data to normal ungrouped structure.  
</details>

<details>
<summary><strong>summarize()</strong> – Compute summary statistics by group</summary>

```{r}
# Average rate by conc
Puromycin %>% group_by(conc) %>% summarize(avg_rate = mean(rate))
```

Aggregates data within each group to produce summary statistics. Often combined with `group_by()`.  
</details>

<details>
<summary><strong>mutate() with groups</strong> – Add or modify columns within groups</summary>

```{r}
# Compute rank of rate within each conc group
Puromycin %>% group_by(conc) %>% mutate(rank_rate = rank(rate))
```

Performs column transformations separately within each group.  
</details>

<details>
<summary><strong>filter() with groups</strong> – Subset rows within groups</summary>

```{r}
# Keep top 1 rate rows within each conc group
Puromycin %>% group_by(conc) %>% slice_max(rate, n = 1)
```

Allows row selection within each group, keeping group-wise logic intact.  
</details>

---

## 🔗 Joins & Bindings {#joins}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section lists core joining operations in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>left_join()</strong> – A join combines rows from two data frames based on a common key.</summary>

```{r}

# Create a copy of puromycin
puromycin <- as_tibble(Puromycin)
head(puromycin)
```

```{r}
# Create a second dataset with additional info
treatment_info <- tibble(
  state = c("treated", "untreated"),
  description = c("Received Puromycin", "Control group")
)
head(treatment_info)
```


```{r}
# Left join: add treatment descriptions
left_join(puromycin, treatment_info, by = "state")
```

Thus:  

- `Left_join(puromycin, treatment_info, by = "state")` merges the description column into the puromycin dataset by matching the state column.  
- Every row in puromycin keeps its original data. The description column is added based on the matching state.  

</details>


<details>
<summary><strong>bind_cols()</strong> – Binding combines data frames either by rows (bind_rows) or by columns (bind_cols).</summary>

```{r}
# Split Puromycin into two groups
treated <- puromycin %>% filter(state == "treated")
untreated <- puromycin %>% filter(state == "untreated")

treated # Show treated, 12 rows
```

```{r}
# Row binding: recombine after filtering
bind_rows(treated, untreated) # now 23 rows
```



```{r}
# Column binding: add an extra column
extra_info <- tibble(source = rep("Lab A", nrow(puromycin)))
extra_info
```

```{r}
bind_cols(puromycin, extra_info) # Columns bound
```

Thus:  
- `bind_rows()` is for stacking datasets vertically (more rows).  
- `bind_cols()` is for combining datasets horizontally (more columns).  

</details>

---

## 🔄 Reshaping Data {#reshaping}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section lists restructure operations of data between long and wide formats in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>pivot_wider()</strong> – Spread key-value pairs across multiple columns. This is useful when you want to separate values into distinct columns.</summary>

First create an extra column with replicates:  

```{r}
Puromycin_reps <- Puromycin %>%
  mutate(replicate = rep(1:2, length.out = n()))
Puromycin_reps
```

Now make the data wide:  

```{r}
Puromycin_wide <- Puromycin_reps %>% pivot_wider(names_from = replicate, values_from = rate)
Puromycin_wide
```

</details>

<details>
<summary><strong>pivot_longer()</strong> – Convert columns into key-value pairs. This is useful when you want to gather multiple columns into a single column.</summary>

```{r}
Puromycin_long <- Puromycin_wide %>% pivot_longer(cols = c("1", "2"),
             names_to = "replicate", values_to = "rate"
)
Puromycin_long
```


</details>

---

## 📈 Visualization {#visualization}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section shows how to plot in ggplot in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>ggplot()</strong> - The function `ggplot()` is used to create visualizations of your data.</summary>

It works with the following layers:

1. Initialization Layer 
2. Geometry Layer 
3. Statistical Layer 
4. Scale Layer 
5. Label Layer 
6. Theme Layer 

To show different layers in ggplot2 using the Puromycin dataset, we build the plot layer by layer, starting with the data and aesthetic mappings, then adding a geometric layer, and finally adding features like labels, themes, or statistical transformations.  

Here is a step-by-step example using R code for a scatter plot with a smooth line, illustrating the key layers:  

- Initialization Layer 

Sets up the data and the initial aesthetic mappings (x, y, color/group)

```{r}
ggplot(Puromycin, aes(x = conc, y = rate, color = state))
```

As you can see, no data are plotted yet. An XY-grid is created and the axis are set.  

- Geometry Layer 

Adds the visual representation of the data (points for a scatter plot)  

```{r}
ggplot(Puromycin, aes(x = conc, y = rate, color = state)) +
  geom_point(size = 3)
```

As you can see, the data is plotted now. Note that the `+` sign is used to add an extra layer. Instead of geom_point, other functions can be used for other plot types.  

- Statistical Layer 

Adds a statistical summary (e.g., a smooth line fit to the data).
For simplicity, we just use a linear model.

```{r}
ggplot(Puromycin, aes(x = conc, y = rate, color = state)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1)
```



Note that for plotting enzyme activity, we normally use the Michaelis-Menten model. This requires more complexity and is omitted in this example. In this case, we used a linear model without standard error ranges for demonstration purposes.  

- Scale Layer 

Controls the mapping from the data values to the visual properties (e.g., color)  

```{r}
ggplot(Puromycin, aes(x = conc, y = rate, color = state)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1) +
  scale_color_manual(name = "Enzyme State", values = c("untreated" = "darkgreen", "treated" = "purple"))
```


- Label Layer 


Adds non-data annotations like titles, axis labels, and caption

```{r}
ggplot(Puromycin, aes(x = conc, y = rate, color = state)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1) +
  scale_color_manual(name = "Enzyme State", values = c("untreated" = "darkgreen", "treated" = "purple")) +
  labs(
  title = "Reaction Rate vs. Substrate Concentration in Puromycin",
  subtitle = "Effect of enzyme state (treated/untreated)",
  x = "Concentration (ppm)",
  y = "Reaction Rate (counts/min)",
  caption = "Data from Puromycin dataset")
```

- Theme Layer
  

Controls the non-data graphical elements (e.g., background, grid lines, font size)  


```{r}
ggplot(Puromycin, aes(x = conc, y = rate, color = state)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1) +
  scale_color_manual(name = "Enzyme State", values = c("untreated" = "darkgreen", "treated" = "purple")) +
  labs(
  title = "Reaction Rate vs. Substrate Concentration in Puromycin",
  subtitle = "Effect of enzyme state (treated/untreated)",
  x = "Concentration (ppm)",
  y = "Reaction Rate (counts/min)",
  caption = "Data from Puromycin dataset") +
  theme_minimal(base_size = 14)
```

This is just a demonstration of the use of the various layers.  
For a complete overview of GGPLOT see [this](https://ggplot2.tidyverse.org/index.html) link.

You can also download a pdf cheatsheet [here](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf).

</details>

---

## 🧰 Utilities {#utilities}

[⬆️ Back to Summary](#tidyverse-overview)

💡 *This section lists some utility operations in the tidyverse. Click on the triangles to expand.*

<details>
<summary><strong>glimpse()</strong> - The function `glimpse()` is great for quick inspection of your data. Helps you verify column types and spot missing or unexpected values.</summary>

```{r}
glimpse(Puromycin)
```
</details>

<details>
<summary><strong>pull()</strong> - The function `pull()` is used to extract a single column from a data frame or tibble as a vector.</summary>

```{r}
Puromycin %>% pull(rate)
```

</details>

<details>
<summary><strong>count()</strong> - The function `count()` is used to tally the number of occurrences of values in one or more columns.</summary>

```{r}
Puromycin %>% count(state)
```


</details>

---

[Go back to the main page](../index.html)  
[Go back to the R overview page](../R/R_01_index.html)  
<a href="#top">⬆️ Back to Top</a>  

---


>This web page is distributed under the terms of the Creative Commons Attribution License which permits unrestricted use, distribution, and reproduction in any medium, provided the original author and source are credited.
>Creative Commons License: CC BY-SA 4.0.

