Skip to content

Variables & Data Types

Every analysis in R starts with storing values. Gene names, read counts, p-values, and sample identifiers all need to live somewhere. Variables give your data a name. Data types determine what R can do with that data. Understanding both is essential before you can write useful bioinformatics code.

R uses the <- operator to assign values to variables. You can also use =, but <- is the standard R convention. You will see it in nearly all R code and documentation.

Store a gene count, a sample identifier, and a significance flag:

gene_count <- 1542
gene_count
[1] 1542
sample_id <- "SAMPLE_01"
sample_id
[1] "SAMPLE_01"
is_significant <- TRUE
is_significant
[1] TRUE

Variable names in R are case sensitive. Use descriptive names with underscores to keep your code readable. Avoid starting names with numbers.

Most numbers in bioinformatics fall into two categories. Expression values, fold changes, and p-values are decimals. Read counts and gene counts are whole numbers. R handles these differently.

By default, R treats numbers as numeric, which stores them as double precision floating point values. This is the right type for expression levels and statistical results.

expression_value <- 23.45
class(expression_value)
[1] "numeric"

For whole number counts, add the L suffix to create an integer. Integers use less memory. This matters when you work with millions of read counts.

read_count <- 15000L
class(read_count)
[1] "integer"

Both types respond to is.numeric() as TRUE. But only the integer passes is.integer().

is.numeric(expression_value)
[1] TRUE
is.integer(read_count)
[1] TRUE

Text data shows up constantly in bioinformatics. Gene names, sample IDs, chromosome labels, and file paths are all character strings. Wrap text in quotes to create a character value.

gene_name <- "BRCA1"
chromosome <- "chr17"
paste("Gene", gene_name, "is on", chromosome)
[1] "Gene BRCA1 is on chr17"

The paste() function joins strings together. The nchar() function counts the number of characters. Both are useful when parsing gene names or sequence data.

nchar(gene_name)
[1] 5

Logical values are either TRUE or FALSE. They drive filtering and decision making in your analysis. Every time you ask “is this gene significant?” or “does this sample pass QC?”, you get a logical result.

Compare a p-value to a threshold:

pvalue <- 0.003
is_significant <- pvalue < 0.05
is_significant
[1] TRUE

Combine conditions with & for AND and | for OR. This is how you build multi-criteria filters for differential expression results.

log2fc <- 2.5
passes_filter <- is_significant & abs(log2fc) > 1
passes_filter
[1] TRUE

This gene has a p-value below 0.05 and an absolute fold change above 1. It passes both filters.

Real biological data has missing values. A failed assay, a dropped sample, or a below-detection measurement all produce gaps in your data. R represents missing data as NA.

Knowing how to detect and handle NA values is critical. One unhandled NA can silently break your calculations.

measurements <- c(5.2, 3.1, NA, 4.8, NA, 6.0)
is.na(measurements)
[1] FALSE FALSE TRUE FALSE TRUE FALSE

Count the missing values:

sum(is.na(measurements))
[1] 2

Many R functions return NA when the input contains any missing values. This is a safety feature, not a bug. It forces you to decide how to handle the gaps.

mean(measurements)
[1] NA

Use na.rm = TRUE to skip missing values in the calculation:

mean(measurements, na.rm = TRUE)
[1] 4.775

Always check your data for NA values before running statistical tests. Document how many values were missing and how you handled them.

Use class() to inspect the type of any variable. This is your first debugging tool when a function throws an unexpected error.

class(gene_name)
[1] "character"
class(is_significant)
[1] "logical"
class(42)
[1] "numeric"
class(42L)
[1] "integer"

Sometimes you need to convert between types. A read count stored as text in a CSV file needs to become a number before you can do math with it. R provides as.* functions for this.

count_string <- "1500"
count_number <- as.numeric(count_string)
count_number + 100
[1] 1600

Convert a number to a character string:

as.character(42)
[1] "42"

Converting a decimal to an integer truncates the decimal portion. R does not round.

as.integer(3.7)
[1] 3

If R cannot convert a value, it returns NA and warns you:

as.numeric("not_a_number")
[1] NA
Warning message:
NAs introduced by coercion

Watch for this warning when reading data files. It often means a column has unexpected text mixed in with numbers.

Type Example Created with Common use in bioinformatics
numeric 23.45 Direct assignment Expression values, p-values, fold changes
integer 15000L L suffix Read counts, gene counts
character "BRCA1" Quotes Gene names, sample IDs, chromosome labels
logical TRUE Comparison operators Significance flags, QC pass/fail
NA NA Missing data Failed assays, below detection limit

You now know how to store and inspect individual values. Most bioinformatics work involves collections of values. Learn how to group data into vectors, lists, and data frames in Data Structures.