R stores information in objects. An object can contain a single value, a list of values, a table, a function, or a more complex structure. For introductory clinical data management, the most important structures are vectors and data frames. A vector is a one-dimensional collection of values of the same general type. A data frame is a rectangular table made of columns and rows. Most clinical datasets imported into R are represented as data frames or tibbles. A tibble is a modern form of data frame used by the tidyverse.
A vector may contain participant IDs:
participant_id <- c(“P001”, “P002”, “P003”, “P004”)
participant_id
The function c() combines values into a vector. Because participant IDs are text, they are enclosed in quotation marks. A vector may also contain numbers:
age_years <- c(34, 29, 41, 52)
age_years
R treats text, numbers, dates, and logical values differently. This matters because clinical datasets include many types of data. A participant ID should usually be treated as text, even if it contains numbers, because it is an identifier rather than a quantity. A heart rate is numeric.
A date of enrolment should be stored as a date. A yes/no field may be stored as a categorical variable or logical value depending on the context.
A data frame combines vectors into columns:
library(tibble)
enrollment_data <- tibble(
participant_id = c(“P001”, “P002”, “P003”, “P004”),
site = c(“Kilifi”, “Nairobi”, “Kilifi”, “Mombasa”),
age_years = c(34, 29, 41, 52),
sex = c(“Female”, “Male”, “Female”, “Male”),
consent_date = as.Date(c(“2026-05-01”, “2026-05-02”, “2026-05-03”, “2026-05-04”))
)
enrollment_data
This code creates a small dataset with four participant records. Each row represents a participant. Each column represents a variable. The as.Date() function tells R to treat the consent dates as dates rather than as plain text. Correct data types are important because date calculations, numeric comparisons, and categorical summaries depend on variables being interpreted correctly.
| Clinical variable | Example value | Suitable R representation | Notes |
|---|---|---|---|
| Participant ID | `P001` | Character | Preserve leading zeros and prefixes |
| Age in years | `34` | Numeric or integer | Check plausible range |
| Consent date | `2026-05-01` | Date | Needed for date comparisons |
| Sex | `Female` | Character or factor | Use controlled categories |
| Randomized | `Yes` | Character, factor, or logical | Depends on data dictionary coding |
| Weight in kg | `62.5` | Numeric | Ensure units are consistent |
| Visit completed | `TRUE` | Logical | Useful for yes/no calculations |
Data frames are central to R-based clinical data management because most checks operate on columns and rows. For example, a missing value check examines whether required columns contain missing entries. A range check examines whether numeric values fall outside expected limits. A consistency check may compare two columns, such as whether discharge_date occurs before admission_date. A duplicate check examines whether one or more identifying columns appear more than once.
In R, missing values are represented as NA. The distinction between a blank string, a zero, and NA is important. A zero may be a valid measurement, such as zero days hospitalized. A blank string may mean that a text field was left empty. NA means the value is missing or unavailable. When importing data from external systems, learners should inspect how missing values were represented and whether the import function converted them appropriately.
follow_up_days <- c(7, 14, NA, 28)
is.na(follow_up_days)
The function is.na() checks which values are missing. The output is a logical vector show ing TRUE for missing values and FALSE for non-missing values. This simple function is one of the building blocks of data quality review.