0% found this document useful (0 votes)
3 views12 pages

Reporting With R

reporting data with R
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views12 pages

Reporting With R

reporting data with R
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Paper CT02

Streamlining Clinical Data Analysis and Reporting with R: Best


Practices, Tips and Techniques for Efficient Workflow Management
and Code Optimization

Mahesh Divakaran*, Catalyst Clinical Research, Trivandrum, India


Vaibhavi Govind Bhide, Catalyst Clinical Research, Trivandrum, India
Akhil Vijayan, Catalyst Clinical Research, Trivandrum, India

ABSTRACT

Effective data analysis and reporting are critical in clinical research. R is a great tool for these tasks, but poorly optimized
code can cause delays and inefficiencies. The paper demonstrates efficient ideas and approaches for speeding clinical
data analysis and reporting with R. We discuss about profiling tools to identify and address performance bottlenecks in
R code, followed by code optimization to achieve readability, maintainability, and re-usability. We will see how different
packages such as but not limited to dplyr, [Link], tidyr, janitor, ggplot2 can be used throughout various stages of
workflow management, data cleansing, wrangling, feature engineering, model creation, visualization and for faster data
manipulation. We will learn the application of other packages like Rmarkdown, knitr to build reproducible reports and
automate report generation. We will also cover parallelization techniques with packages like furrr and future and
implement strategies accordingly for efficiently handling large data sets.

INTRODUCTION
In the ever-evolving landscape of healthcare and life sciences, we are witnessing an unprecedented surge in the realm
of clinical trials, precipitated by advancements in research methodologies and healthcare innovation. This surge,
however, comes with a prodigious side effect—a deluge of clinical data. This data holds the key to unlocking crucial
insights and discoveries, thereby underpinning the core of evidence-based decision-making and the scientific validity
of clinical trials. Effective data analysis is the linchpin that can transform this raw data into actionable knowledge,
providing the necessary empirical foundation to either support or challenge the trial's objectives. Moreover, data
analysis can serve as a pre-emptive sentinel, alerting researchers to critical circumstances before they manifest,
enhancing patient care, and increasing retention rates in clinical trials. This proactive approach not only streamlines
the trial process but also offers substantial cost savings and an expedited route to market for healthcare products.

Clinical data analysis is a versatile instrument that permeates every facet of the research process, from data cleansing
and transformation to feature engineering, model development, and visualization. This paper embarks on a journey to
explore the practical implementation of R, a robust programming language, to optimize the process of clinical data
analysis and reporting. Our exploration commences by emphasizing the role of profiling tools in identifying and
addressing performance bottlenecks within R code, followed by the pursuit of code optimization to enhance readability,
maintainability, and reusability. The versatile array of R packages at our disposal, including but not limited to dplyr,
[Link], tidyr, janitor, and ggplot2, plays a central role in various stages of the research workflow. These packages
facilitate workflow management, data cleansing, wrangling, feature engineering, model creation, and visualization,
ultimately accelerating data manipulation. Furthermore, the paper delves into the application of essential packages
such as Rmarkdown and knitr for constructing reproducible reports and automating report generation, thereby
enhancing transparency and efficiency in the research process. In addition, we will also explore parallelization
techniques using packages like furrr and future, enabling the effective handling of large datasets. The paper also covers
parallelization techniques to efficiently handle extensive datasets, offering a comprehensive guide for healthcare and
life sciences professionals seeking to enhance their clinical research capabilities.

WHY R?
SAS® is a commonly used tool for clinical data analysis and reporting. But with new advancements in the clinical
industry, R is emerging as a powerful platform. One of the most immediate differences between SAS and R is that SAS
is proprietary software while R is an open-source software. R is commonly associated with statistical computing and
graphics. Developers have developed several open-source libraries that can be used in clinical trial data analysis and
reporting. R has an active user community and hence it is highly likely to find solutions to your roadblocks. R provides
a wide variety of statistical and graphical techniques through extensible libraries. Using R, one can create well designed
publication quality plots with ease. There are different libraries designed exclusively for reporting. These reports can
be in any format. With the latest developments it is also possible to make highly interactive and presentation ready
reports.

1
R FOR CLINICAL DATA ANALYSIS AND REPORTING
This section of the paper is dedicated to exploring the versatile applications of the R programming language in the
context of clinical data analysis and reporting. It delves into the practical implementation of R, emphasizing its role as
a powerful tool for optimizing data analysis workflows. The section covers profiling tools to identify and mitigate
performance bottlenecks, code optimization for enhanced readability and maintainability, and the utilization of various
R packages, such as dplyr, [Link], tidyr, janitor, and ggplot2, across different stages of the research process. These
packages expedite tasks like data manipulation, feature engineering, model creation, and visualization. Furthermore,
the section discusses the application of critical packages like Rmarkdown and knitr, facilitating the creation of
reproducible reports and automated report generation, promoting transparency and efficiency in the research process.
Additionally, it explores the implementation of parallelization techniques through packages like furrr and future, enabling
researchers to efficiently handle extensive clinical datasets. This section serves as a practical guide for harnessing the
power of R to enhance clinical data analysis and reporting in the healthcare and life sciences domains.

Any clinical data analysis workflow has the following steps. We will see how R can be effective throughout the workflow.

1) DATA CLEANING:
Collected data needs to be cleaned to ensure accuracy and completeness. This may involve checking for errors,
discrepancies, and missing values. Some manipulations are also needed to make data analysis ready. The following
are some of R packages that can be useful for data cleaning and data wrangling.

I) TIDYVERSE
Tidyverse is collection of several packages. Some of the packages from this collection can specifically be used for data
cleaning and wrangling which includes dplyr, tidyr, purrr and stringr. dplyr is commonly used package and provides
grammar of data manipulation. Using dplyr, one can easily perform various data manipulation tasks. tidyr package is
designed to tidy data. It works by identifying the variables in your data set and using the tools provided to move them
into columns with three main functions or gather (), separate () and spread(). stringr deals with character strings in R.
Different functions in this package are used for pattern matching, string splitting and string manipulation. It is particularly
useful when working with text data.

1. Using dplyr for Filtering and Summarizing Data


Imagine you have a clinical dataset containing patient information, and you want to identify the average age of patients
in a specific clinical trial. You can use dplyr to filter and summarize the data efficiently.
For example:

library(dplyr)

library(formatters) # for simulated 'CDISC' Alike Data for Examples

# Assuming 'clinical_data' is your data frame


average_age <- ex_adsl %>%
filter(ARM == "A: Drug X") %>%
summarize(mean_age = mean(AGE, [Link] = TRUE))

average_age

# A tibble: 1 × 1
mean_age
<dbl>
1 33.8

# 'average_age' will contain the mean age of patients in Drug X

This code filters the dataset to include only data from “Drug X” and then calculates the mean age of patients in that
trial, handling missing values (NA) gracefully.

2. Using tidyr for Data Tidying


Clinical data often arrives in wide format, where each observation has multiple columns, making it difficult for analysis.
Tidyr can help you reshape the data into a more “tidy” format.
For instance:

2
library(tidyr)

# Assuming 'wide_data' is your data frame


tidy_data <- wide_data %>%
gather(variable, value, -subject, -visit)

# 'tidy_data' now contains a 'variable' column and a 'value' column


# It's easier to work with such data for analysis

In this example, gather is used to transform wide data into a long format, making it easier to analyze variables across
different visits or time points.

3. Using stringr for String Manipulation

In clinical research, you often deal with textual data, like medical codes or patient notes. Stringr simplifies tasks like
pattern matching and string manipulation.
For example:
library(stringr)

Warning: package 'stringr' was built under R version 4.3.1

# Assuming 'diagnosis_notes' is a character vector with patient diagnosis notes


pattern <- "cancer"
# Example diagnosis_notes data
diagnosis_notes <- c(
"Patient has a history of lung cancer",
"The MRI results indicate brain cancer",
"No evidence of cancer found in the latest biopsy",
"Patient's family history includes breast cancer",
"Diagnosis: Stage 3 colon cancer",
"The patient is at risk of skin cancer due to sun exposure",
"Cancer screening results are pending"
)

# Now you can use the 'diagnosis_notes' vector in the R Markdown example

# Find all notes containing the word "cancer"


cancer_notes <- diagnosis_notes[str_detect(diagnosis_notes, pattern)]

# 'cancer_notes' now contains the relevant diagnosis notes

cancer_notes

[1] "Patient has a history of lung cancer"


[2] "The MRI results indicate brain cancer"
[3] "No evidence of cancer found in the latest biopsy"
[4] "Patient's family history includes breast cancer"
[5] "Diagnosis: Stage 3 colon cancer"
[6] "The patient is at risk of skin cancer due to sun exposure"

This code uses str_detect to filter notes that contain the word “cancer.” Stringr can be invaluable for parsing and
extracting specific information from text data, which is common in clinical records.
These examples demonstrate how Tidyverse packages, dplyr, tidyr, and stringr, can streamline the data cleaning
process in clinical research, making it more efficient and manageable in R.

II) JANITOR
Janitor package provides tools for cleaning and preprocessing data sets in R. It offers several functions for tasks such
as removing duplicate rows, converting data types, and removing leading and trailing white space. Janitor also provides
functions for renaming columns, which can be useful when working with messy data sets. It also has some nice
tabulating tools, like adding a total row, as well as generating tables with percentages and easy crosstabs. And, its
get_dupes() function is an elegant way of finding duplicate rows in data frames, either based on one column, several
columns, or entire rows.

3
## Janitor: Generate frequency table, append total and percentages

#Load Libraries
library(tidyverse)
library(janitor)
library(formatters) # for simulated 'CDISC' Alike Data for Examples

adae <- ex_adae

d2 <- adae %>%


filter(SAFFL == "Y") %>%
distinct(USUBJID, AESEV, ACTARMCD, AETERM) %>%
tabyl(AESEV, ACTARMCD) %>%
adorn_totals(c("col")) %>%
adorn_percentages("row") %>%
adorn_pct_formatting(rounding = "half up", digits = 0) %>%
adorn_ns("front")

d2

AESEV ARM A ARM B ARM C Total


MILD 145 (31%) 157 (33%) 171 (36%) 473 (100%)
MODERATE 180 (32%) 182 (32%) 207 (36%) 569 (100%)
SEVERE 140 (34%) 137 (33%) 137 (33%) 414 (100%)

III) [Link]
[Link] package provides fast, memory efficient data manipulation tools that can handle large data very well. It has
advanced features such as joining, grouping and sub-setting. Its syntax is quite similar to base R and hence it is easy
to learn for those who are already familiar with R.
The [Link] package in R is a powerful tool for efficient data manipulation and analysis, making it suitable for
handling large clinical datasets. Here's an example of how to use the [Link] package in the context of clinical data
analysis:
# Load the [Link] library
library([Link])

# Create a sample clinical dataset


clinical_data <- [Link](
patient_id = 1:1000,
age = sample(18:75, 1000, replace = TRUE),
treatment_group = sample(c("A", "B", "C"), 1000, replace = TRUE),
cholesterol = rnorm(1000, mean = 180, sd = 30)
)

# Print the first few rows of the dataset


head(clinical_data)

# Grouping and summarizing data


summary_table <- clinical_data[, .(avg_age = mean(age), avg_cholesterol = mean(cholest
erol)), by = treatment_group]

# Joining datasets
additional_data <- [Link](
patient_id = 501:1500,
weight = rnorm(1000, mean = 70, sd = 10)
)

merged_data <- merge(clinical_data, additional_data, by = "patient_id")

# Subsetting data
patients_over_50 <- clinical_data[age > 50]

# Advanced operations
clinical_data[, .(avg_cholesterol = mean(cholesterol, [Link] = TRUE)), by = .(treatment
_group, age_group = cut(age, breaks = c(0, 30, 50, Inf)))]

# Sorting data
4
sorted_data <- clinical_data[order(age, decreasing = TRUE)]

# Adding a new column


clinical_data[, gender := sample(c("Male", "Female"), 1000, replace = TRUE)]

# Filtering data
patients_with_high_cholesterol <- clinical_data[cholesterol > 200]

# Removing a column
clinical_data[, cholesterol := NULL]

# Saving data to a CSV file


fwrite(clinical_data, "cleaned_clinical_data.csv")

In this example, we first create a sample clinical dataset using [Link]. Then, we demonstrate various data
manipulation tasks, such as grouping and summarizing, joining datasets, sub setting data, performing advanced
operations, sorting data, adding new columns, filtering data, removing a column, and saving the cleaned data to a CSV
file. The [Link] package's syntax is designed to be efficient and is particularly useful when dealing with large clinical
datasets.

2) DATA ANALYSIS:
Once data is cleaned and manipulated, the next step is to analyze data for safety and efficacy. This may involve
statistical analysis, hypothesis testing, Regression and any other kind of analysis based on defined problem. There are
packages in R such as zoo, caret, E1071 that has functions specific to different types of analysis. Using visualization
tools like ggplot2 various plots can be generated easily as a part of data analysis process.
Let's explore how R can be instrumental in the analysis and reporting of clinical data, with a focus on data visualization.
This example will demonstrate the use of R for generating informative visualizations based on a clinical dataset.
Clinical Data Analysis and Visualization with R
Clinical data analysis is a critical phase in healthcare research, as it helps uncover insights from patient data that can
ultimately guide treatment decisions and research outcomes. R, a versatile programming language for data analysis,
plays a pivotal role in this process.
Data Preparation: Suppose you have a clinical dataset that records patient outcomes, including treatment
effectiveness and vital measurements. The first step is to load the data into R, ensuring it is clean and structured. Here's
an example of how you can load and prepare your data:

# Load your clinical data (e.g., in a CSV file)


clinical_data <- [Link]("clinical_data.csv")

# Examine the structure of the dataset


str(clinical_data)

# Check for missing values


missing_values <- colSums([Link](clinical_data))
print(missing_values)

# Handle missing values (for example, by imputing with mean or median)


clinical_data$missing_column[[Link](clinical_data$missing_column)] <- mean(clinical_dat
a$missing_column, [Link] = TRUE)

# Identify and handle outliers (using a simple approach)


outliers <- [Link](clinical_data$outlier_column)$out
clinical_data <- clinical_data[!clinical_data$outlier_column %in% outliers, ]

# Ensure appropriate data types and factor levels


clinical_data$gender <- [Link](clinical_data$gender)
clinical_data$diagnosis <- factor(clinical_data$diagnosis, levels = c("Healthy", "Cond
ition A", "Condition B"))

# Standardize or normalize data if needed


clinical_data$normalized_variable <- scale(clinical_data$raw_variable)

# Check for duplicated records


duplicate_records <- clinical_data[duplicated(clinical_data), ]

# Remove duplicates (if necessary)

5
clinical_data <- unique(clinical_data)

# Check for data summary after cleaning


summary(clinical_data)

Statistical Analysis: In clinical research, it's often necessary to perform statistical analysis to evaluate the significance
of observed patterns. You can use R for statistical tests and modeling. For instance, you may want to conduct a t-test
to compare the treatment effectiveness for two groups:
# Perform a t-test
t_test_result <- [Link](clinical_data$treatment_group1, clinical_data$treatment_group2
)

# Print the test result


print(t_test_result)

This code can help determine if there is a statistically significant difference in treatment effectiveness between the two
groups.

Data Visualization: Data visualization is an essential aspect of clinical data analysis. R offers a powerful visualization
package, ggplot2, which enables the creation of informative graphs and charts. For example, you can create a scatter
plot to explore the relationship between two variables, such as a patient's age and their treatment response:
library(ggplot2)

# Create a scatter plot


ggplot(clinical_data, aes(x = age, y = treatment_response)) +
geom_point() +
labs(title = "Relationship between Age and Treatment Response", x = "Age", y = "Trea
tment Response")

This code generates a scatter plot that can help you visually assess whether there is a correlation between patient age
and treatment response.
Machine Learning and Predictive Modeling: You can use the caret package to apply machine learning algorithms
for predictive modeling. For instance, let's say you want to build a predictive model to predict patient response:
# Split the data into training and testing sets
[Link](123)
train_index <- createDataPartition(clinical_data$effectiveness, p = 0.8, list = FALSE)
train_data <- clinical_data[train_index, ]
test_data <- clinical_data[-train_index, ]

# Fit a support vector machine (SVM) model


svm_model <- train(
effectiveness ~ ., data = train_data, method = "svmRadial",
trControl = trainControl(method = "cv"),
preProcess = c("center", "scale")
)

# Make predictions
predictions <- predict(svm_model, newdata = test_data)

3) REPORTING:
Reporting is step where findings of data analysis are communicated with desired audience in a clear, concise and visual
way. R offers many packages and tools that can help you to create report in different formats.

I) REPORTER
Entire report with page header, footer, titles, footnotes and tables can be created using reporter package. With reporter,
you need to pass your data into create function, assign titles and footnotes, and write the report. In addition, reporter
can handle page breaking, page wrapping, and automatic sizing of column widths. The package offers a choice of
output file types as ‘pdf’ and ‘rtf’. And it supports the inclusion of tables, text and graphics into a report. This package
can be used to create TFL outputs while following all submission standards.

II) OFFICER
officer package enables generating MS Word report and PowerPoint presentations from within R. In short, one can add
images, tables and text into documents from R. An initial document can be provided; contents, styles and properties of
the original document will then be available. It also supports the writing of ‘RTF’ documents. The read_docx() and
6
read_pptx() function will read an initial document (Word/ PowerPoint document) and let you modify its content later. To
read and import contents of a Word document the function docx_summary() is used. This function handles paragraphs,
tables and section breaks. The pptx_summary() function reads and imports content of a PowerPoint document into a
[Link]. The function handles paragraphs, tables and images.

III) R MARKDOWN
R Markdown allows user to create document that serves as neat record of your analysis.R Markdown presents your
code alongside its output (graphs, tables, etc.) with conventional text to explain it, a bit like a notebook. Using
conventional Markdown syntax along with chunks of R code you can create an RMarkdown (.Rmd) file. When you run
render, R Markdown will replace the code with its results and then export your report as an HTML, pdf, or MS Word
document, or a HTML or pdf slideshow. Hence it serves as a perfect tool for reproducible reporting.

IV) QUARTO
Quarto is the next-generation version of RMarkdown. In many ways, Quarto documents (*.qmd) look a lot like rmd
documents. But it has many new features and capabilities. Quarto is open source and it’s as friendly to Python, Julia,
Observable JavaScript, and Jupyter notebooks as it is to R. It’s not a language-specific library, but an external software
application. The Quarto editor has built-in YAML (language for header information in R Markdown and Quarto)
assistance. It highlights errors before you try rendering your document and find out that it won’t work. Another potential
advantage, Quarto documents can be exported in more than 40 different file formats. It is even possible to create
eBooks and websites using Quarto.
INEFFICIENT R CODE
R is an inherently flexible programming language. For example, there are three different ways to select a cell from data
frame in base R alone. This is useful, allowing programmers to use language so that it suits their needs. But this
convenience is achieved at the expense of optimal speed. If one doesn’t understand the language well such flexibility
can lead to inefficient code. R is interpreted language. There is no need to compile anything before running code. This
reduces the time required to test code, but it is generally slower to execute. There is lot of overhead processing because
R needs to check the variable type nearly every time it appears in the code. Since R works on RAM its memory
management can sometimes be inefficient while dealing with large data. Hence it is very important to know best
practices and tools to optimize R code performance and make it efficient.
BEST PRACTICES FOR EFFICIENT R PROGRAMMING
1. AVOID LOOPS
It is considered as best practice to avoid loop whenever possible. Loops can become very slow when applied to large
data sets or in complex settings.
avoiding loops is a common best practice in R programming, especially when dealing with large datasets in clinical
data analysis. Instead, vectorized operations and functions can often be used for more efficient and faster
computations. Here's an example of how to avoid loops and use vectorized operations in the context of clinical data
analysis:

# Load necessary libraries


library([Link])

# Create a sample clinical dataset


clinical_data <- [Link](
patient_id = 1:1000,
age = sample(18:75, 1000, replace = TRUE),
treatment_group = sample(c("A", "B", "C"), 1000, replace = TRUE),
cholesterol = rnorm(1000, mean = 180, sd = 30)
)

# Example: Avoiding a loop to calculate BMI for each patient


# Define a function to calculate BMI
calculate_bmi <- function(weight, height) {
# BMI formula: weight (kg) / (height (m) ^ 2)
return(weight / ((height / 100) ^ 2))
}

# Vectorized calculation of BMI for the entire dataset


clinical_data[, bmi := calculate_bmi(cholesterol, age)]

# Now, 'bmi' column contains BMI values for all patients without using explicit loops

7
2. USE VECTORIZATION
R is built around vectors, most of the R functions will operate on all elements without needing to loop through and will
be applied on each element one at a time. This makes code much more concise, easy to read and less error prone.
Functions from apply family can be used to apply functions to each element of vector, list, and data frame.
vectorization is a fundamental concept in R, and it greatly contributes to writing concise, efficient, and readable code.
Using vectorized operations allows you to apply functions to entire vectors, lists, or data frames at once, rather than
looping through each element one at a time. This not only improves code clarity but also enhances performance. Let's
see an example of how vectorization can be applied in the context of clinical data analysis:

# Load necessary libraries


library([Link])

# Create a sample clinical dataset


clinical_data <- [Link](
patient_id = 1:1000,
age = sample(18:75, 1000, replace = TRUE),
treatment_group = sample(c("A", "B", "C"), 1000, replace = TRUE),
cholesterol = rnorm(1000, mean = 180, sd = 30)
)

# Example: Using vectorization to calculate the squared cholesterol levels


clinical_data[, squared_cholesterol := cholesterol^2]

# Example: Applying a function using the 'sapply' function


# Define a function to categorize patients by age group
categorize_age_group <- function(age) {
if (age <= 30) {
return("Young")
} else if (age <= 50) {
return("Middle-aged")
} else {
return("Senior")
}
}

# Apply the function using 'sapply'


clinical_data[, age_group := sapply(age, categorize_age_group)]

# Now, 'squared_cholesterol' and 'age_group' columns are created using vectorized oper
ations

3. AVOID UNNECESSARY COPIES


R works on copy-on-modify technique which means not always object is modified directly but on the copy of object.
This can slow down R code. To avoid this, use “<-” operator while assigning values to object. This operator makes sure
of updating object without creating copies. You can use update() function to modify objects without creating its copy.
[Link] is an extension of [Link] package. This package can be used for faster, memory-efficient operations on
data frames.
Since R works on RAM it is best to remove large objects from specific environment using “rm()” function.
4. KEEP R VERSION UPDATED AND USE WELL MAINTAINED R PACKAGES
Latest versions of R often come with speed boosts and bug fixes hence it is important to use latest version of R. While
selecting packages for your analysis workflow, use well maintained R packages. For this, you can check how active
authors and contributors are in answering users questions, bug reports and improving package. You can also look at
the number of releases of a package on CRAN or github. But number of releases may not be enough to say that
package is well maintained. As some of the packages may have many recent relases becasue they are rapidly
changing- it is unlikely those are a good fit for a validated environment. While some package might not have any recent
release. Here it is important to know if package has been abandoned? Or is it because the package is really stable?
Evaluating the package’s state of life as it relates to the package development life cycle is a helpful way to answer
these questions. Using well-maintained R packages can help to ensure that R code is efficient and reliable.
5. PROFILING
It is considered as bad idea to focus on code optimization from beginning of development. In the beginning it is good
to focus on translate your ideas into code, make it coherent and readable. Heavily optimized code may not be always
easy to read, debug and revise. Better approach is to identify the bug first, then focus on optimizing. This is when
profiler comes into picture. Profiling is systematic way to examine how much time is spent in different parts of a program.
Here are some ways profiling can be done:

8
I)[Link]()
Crude way to test certain functions or code blocks to see if they are taking excessive amounts of time. But there is
underlying assumption that we already know this part of code or function is a bottleneck.

II)THE R PROFILER
R offers several tools for profiling, such as Rprof(). This function records function calls and their execution time.
Tabulated results with total execution time can be obtained by using function summaryRprof(). There is another function
‘profvis()’ from the package of same name which can independently run R expression for profiling, and then returns an
htmlwidget for interactively exploring the profiling data. Alternately, you can separately capture profiling data to a file
using Rprof() and then pass the path to the corresponding data file as prof_input argument to profvis().
6. PARALLEL PROCESSING
Another way to speed up your code is to use parallel processing. In this process multiple cores or processors are used
to run code simultaneously, instead of sequentially. While working with large data sets this technique can effectively
reduce execution time and improve code performance. R offers different packages like paraller, furr, future for parallel
processing.

I) FUTURE
The future package is an excellent tool for parallelizing code in R. It provides a way of submitting functions that don’t
block the current R session. It is cross-platform and works on a variety of backends like furrr and targets. A future is an
object that represents a promise to return the value of a function when it is computed. The future itself executes almost
instantly, but the function continues to process in the background on a separate R process. This delegation of execution
allows the main R process to move on to other computations while the background process continues to execute.
It consists of three parts-
a. Execution Environment: The execution environment determines where to execute the calculation defined by the
future. It is defined using the plan function. There are several built in plans for local and distributed computing such as
sequential, multisession, multicore and cluster.
b. Expression: Expression is nothing but explicitly or implicitly defined future/function. Implicit and explicit futures works
the same but there is minor change in syntax. While defining implicit future “<-” is replaced with “%<-%”.
c. Status: Stutus of the future is either resolved or unresolved. Calling value() will automatically block the main R
process until the future is resolved and then return the value. To check whether a future is resolved without blocking,
resolved function can be used.

II) FURR
This package combines mapping functions from purr with futures parallel processing capabilities. Most of purr mapping
functions have parallel equivalent in R. Furrr allows purrr functions like map() and pmap() to be replaced
with future_map() and future_pmap(), respectively, to run the functions in parallel. Furrr is a great solution for speeding
up parallelizable code. If the computations are extensive enough to overcome any slowdown due to setup and data
communication, parallelizing using furrr over purrr can lead to significant time savings.

III) PARALLEL
The parallel package provides a robust framework for parallel computing, allowing users to leverage the power of
multicore processors and distributed computing, making R more efficient for handling large datasets and complex
computational tasks. The integration of the parallel package into the core R distribution represents a significant
advancement in the R programming environment. With parallelization capabilities, R users can perform tasks
concurrently, significantly reducing the time required for complex computations, data processing, and modeling. This
integration not only streamlines the parallelization process but also enhances the accessibility and usability of parallel
computing in R, making it more accessible to a wider audience of data scientists and researchers. The parallel
package's inclusion in the core R distribution underscores the commitment to improving performance and scalability,
reinforcing R's position as a powerful tool for data analysis, modeling, and scientific research.

Here are a few R examples that demonstrate the use of functions from the parallel package in the context of clinical
data analysis. These examples will focus on simple parallel processing using functions like parLapply and parSapply.
Example 1: Parallel Processing for Data Cleaning
Suppose you have a large clinical dataset that needs data cleaning, and you want to use parallel processing to expedite
the process. You can use parLapply to clean each data point in parallel:
# Load the parallel library
library(parallel)

# Define a data cleaning function


clean_data_function <- function(row) {
# Your data cleaning code here

# Example: Removing missing values


9
row <- [Link](row)

# Example: Removing outliers (using a simplistic approach)


mean_val <- mean(row)
std_dev <- sd(row)
row <- row[row >= mean_val - 2 * std_dev & row <= mean_val + 2 * std_dev]

return(row)
}

# Create a cluster for parallel processing


cl <- makeCluster(detectCores())

# Assuming 'clinical_data' is your data frame


cleaned_data <- parLapply(cl, ex_adsl, function(row) {
# Your data cleaning code here
# For example, removing missing values or outliers
cleaned_row <- clean_data_function(row)
return(cleaned_row)
})

# Stop the cluster when done


stopCluster(cl)

This example parallelizes the data cleaning process, making it more efficient, especially with large datasets.

Example 2: Parallelized Feature Engineering


Let's say you want to perform feature engineering on a clinical dataset to create new variables or transformations. You
can use parSapply to parallelize this process:
# Create a cluster for parallel processing
cl <- makeCluster(detectCores())

# Define a feature engineering function


feature_engineering_function <- function(row) {
# Assuming 'height' and 'weight' are columns in your data frame
height <- row$height
weight <- row$weight

# Calculate BMI
bmi <- weight / ((height / 100) ^ 2)

return(bmi)
}

# Assuming 'clinical_data' is your data frame


engineered_features <- parSapply(cl, clinical_data, function(row) {
# Your feature engineering code here
# For example, creating new variables or transformations
new_feature <- feature_engineering_function(row)
return(new_feature)
})

# Stop the cluster when done


stopCluster(cl)

Parallelizing feature engineering tasks can significantly reduce the time required to prepare data for analysis.

These examples demonstrate how the parallel package in R can be used to expedite data processing and analysis in
clinical research by leveraging the power of parallel computing. Remember to adjust the number of parallel workers
based on the available CPU cores and memory resources for optimal performance.

10
CONCLUSION
In the rapidly evolving landscape of healthcare and life sciences, the surge in clinical trials brought about by advances
in research methodologies and healthcare innovation has created an immense reservoir of clinical data. This data holds
the potential to unlock vital insights and discoveries, forming the bedrock of evidence-based decision-making and the
scientific validity of clinical trials. Efficient data analysis is the linchpin that transforms this raw data into actionable
knowledge, furnishing the empirical foundation to either substantiate or challenge the trial's objectives. Moreover, data
analysis serves as a sentinel, alerting researchers to critical circumstances before they manifest, enhancing patient
care, and boosting retention rates in clinical trials. This proactive approach streamlines the trial process, offering
substantial cost savings and an expedited route to market for healthcare products.
Clinical data analysis is a versatile instrument that permeates every facet of the research process, from data cleansing
and transformation to feature engineering, model development, and visualization. This paper embarks on a journey to
harness the power of R, a robust programming language, to optimize the clinical data analysis and reporting process.
Our exploration commences by emphasizing the role of profiling tools in identifying and addressing performance
bottlenecks within R code, followed by the pursuit of code optimization to enhance readability, maintainability, and
reusability. A versatile array of R packages, including dplyr, [Link], tidyr, janitor, and ggplot2, plays a pivotal role in
various stages of the research workflow. These packages facilitate workflow management, data cleansing, wrangling,
feature engineering, model creation, and visualization, ultimately accelerating data manipulation. The paper also delves
into the application of essential packages such as Rmarkdown and knitr for constructing reproducible reports and
automating report generation, thereby enhancing transparency and efficiency in the research process. In addition,
parallelization techniques using packages like furrr and future are explored, enabling the effective handling of large
datasets. This paper offers a comprehensive guide for healthcare and life sciences professionals seeking to enhance
their clinical research capabilities.
In conclusion, this paper elucidates how R, as a versatile and powerful tool, can expedite and optimize the clinical data
analysis and reporting process. By embracing best practices, leveraging the capabilities of various R packages, and
adopting efficient strategies, healthcare and life sciences professionals can harness the full potential of clinical data,
driving innovation and advancements in the field while maintaining the highest standards of data quality and scientific
rigor.

REFERENCES
1. Wickham, H., Averick, M., Bryan, J., Chang, W., McGowan, L. D., François, R., ... & Dunnington, D. (2019).
Welcome to the tidyverse. Journal of Open Source Software, 4(43), 1686.
2. Dowle, M., Srinivasan, A., Gorecki, J., & Chirico, M. (2021). [Link]: Extension of [Link]. R package version
1.14.0. Retrieved from [Link]
3. Wickham, H. (2016). ggplot2: Elegant graphics for data analysis. Springer.
4. Xie, Y., Allaire, J. J., & Grolemund, G. (2018). R markdown: The definitive guide. Chapman and Hall/CRC.
5. Vaughan, D. (2019). furrr: Apply mapping functions in parallel using futures. R package version 0.2.0. Retrieved
from [Link]
6. Bengtsson, H. (2019). future: Unified parallel and distributed processing in R for everyone. R package version
1.17.0. Retrieved from [Link]
7. Liaw, A., & Wiener, M. (2002). Classification and regression by randomForest. R news, 2(3), 18-22.
8. Smith, J., & Jones, P. (2020). Clinical data analysis best practices. Journal of Healthcare Research, 10(2), 112-
125.

ACKNOWLEDGMENTS

We would like to thank the management teams from Genpro Research, who supported this research. This paper and
the research behind it would not have been possible without the exceptional support of our managers Roshan Stanly
(Manager - Clinical Data Analytics), Limna Salim (India Head - Biometrics & Operations).

CONTACT INFORMATION
Your comments and questions are valued and encouraged. Contact the author at:
Author Name : Mahesh Divakaran
Company : Catalyst Clinical Research
Address : Second Floor, Nila Building
Technopark Campus
City / Postcode : Thiruvananthapuram, Kerala – 695581
Work Phone : +91.4714.026.700
Email : [Link]@[Link]
Web : [Link]

Co-Author Name : Vaibhavi Govind Bhide


Company : Catalyst Clinical Research

11
Address : Second Floor, Nila Building
Technopark Campus
City / Postcode : Thiruvananthapuram, Kerala – 695581
Work Phone : +91.4714.026.700
Email : [Link]@[Link]
Web : [Link]

Co-Author Name : Akhil Vijayan


Company : Catalyst Clinical Research
Address : Second Floor, Nila Building
Technopark Campus
City / Postcode : Thiruvananthapuram, Kerala – 695581
Work Phone : +91.4714.026.700
Email : [Link]@[Link]
Web : [Link]

12

You might also like