Book Image

R Bioinformatics Cookbook - Second Edition

By : Dan MacLean
Book Image

R Bioinformatics Cookbook - Second Edition

By: Dan MacLean

Overview of this book

The updated second edition of R Bioinformatics Cookbook takes a recipe-based approach to show you how to conduct practical research and analysis in computational biology with R. You’ll learn how to create a useful and modular R working environment, along with loading, cleaning, and analyzing data using the most up-to-date Bioconductor, ggplot2, and tidyverse tools. This book will walk you through the Bioconductor tools necessary for you to understand and carry out protocols in RNA-seq and ChIP-seq, phylogenetics, genomics, gene search, gene annotation, statistical analysis, and sequence analysis. As you advance, you'll find out how to use Quarto to create data-rich reports, presentations, and websites, as well as get a clear understanding of how machine learning techniques can be applied in the bioinformatics domain. The concluding chapters will help you develop proficiency in key skills, such as gene annotation analysis and functional programming in purrr and base R. Finally, you'll discover how to use the latest AI tools, including ChatGPT, to generate, edit, and understand R code and draft workflows for complex analyses. By the end of this book, you'll have gained a solid understanding of the skills and techniques needed to become a bioinformatics specialist and efficiently work with large and complex bioinformatics datasets.
Table of Contents (16 chapters)

Computing new data columns from existing ones and applying arbitrary functions using mutate()

Data frames are the core data structure in R for storing and manipulating tabular data. They are similar to a table in a relational database or a spreadsheet, with rows representing observations and columns representing variables. The mutate() function in dplyr is used to add new columns to a data frame by applying a function or calculation to existing columns; it can be used on both data frames and nested datasets. A nested dataset is a data structure that contains multiple levels of information, such as lists or data frames within data frames.

Getting ready

In this recipe, we’ll use a very small data frame that will be created in the recipe and the dplyr, tidyr, and purrr packages.

How to do it…

The functionality offered by the mutate() pattern is exemplified in the following steps:

  1. Add some new columns:
    library(dplyr)df <- data.frame(gene_id = c("gene1", "gene2", "gene3"),                 tissue1 = c(5.1, 7.3, 8.2),                 tissue2 = c(4.8, 6.1, 9.5))df <- df |> mutate(log2_tissue1 = log2(tissue1),                    log2_tissue2 = log2(tissue2))
  2. Conditionally operate on columns:
    df |> mutate_if(is.numeric, log2)df |> mutate_at(vars(starts_with("tissue")), log2)
  3. Operate across columns:
    library(dplyr)df <- data.frame(gene_id = c("gene1", "gene2", "gene3"),                 tissue1 = c(5.1, 7.3, 8.2),                 tissue2 = c(4.8, 6.1, 9.5),                 tissue3 = c(8.5, 12.5, 6.5))df <- df |>   rowwise() |>    mutate(mean = mean(c(tissue1, tissue2, tissue3)),         stddev = sd(c(tissue1, tissue2, tissue3))         )
  4. Operate on nested data:
    df <- data.frame(gene_id = c("gene1", "gene2", "gene3"),                 tissue1_value = c(5.1, 7.3, 8.2),                 tissue1_pvalue = c(0.01, 0.05, 0.001),                 tissue2_value = c(4.8, 6.1, 9.5),                 tissue2_pvalue = c(0.03, 0.04, 0.001)                 ) |>       tidyr::nest(-gene_id, .key = "tissue")df <- df |> mutate(tissue = purrr::map(tissue, ~ mutate(.x, value_log2 = log2(.[1]),pvalue_log2 = log2(.[2])) ))

These are the various ways we can work with mutate() on different data frames to different ends.

How it works…

In step 1, we start by creating a data frame containing three genes, with columns representing the values of each gene. Then, we use the [mutate(){custom-style='P - Code'} function in its most basic form to apply the log2 transformation of the values into new columns.

In step 2, we apply the transformation conditionally with mutate_if(), which applies the specified function to all columns that match the specified condition (in this case, is.numeric), and mutate_at() to apply the log2 function to all columns that start with the name tissue.

In step 3, we create a bigger data frame of expression data and then use the rowwise() function in conjunction with mutate() to add two new columns, mean and stddev, which contain the mean and standard deviation of the expression values across all three tissues for each gene. If we just use mutate() on the vector, the function will be applied to the entire column instead of the rows. As we need to calculate the mean and standard deviation of the expression values across all tissues, this would be difficult to achieve just by using mutate() on vectors in the standard column-wise fashion.

Finally, we look at using mutate() in nested data frames. We begin by creating a data frame of genes and expression values and use the nest() function to create a nested data frame. We can then use the combination of mutate() and map() functions from the purrr package, to extract the tissue1_value and tissue2_value columns from the nested part of the data frame.