Day 1: R Basics and data cleaning

Hands-on tutorial using the Global Change Factors dataset (MultiFactor_data.csv)

0. Overview

What you’ll practice today

  • Loading a CSV in R (several ways)

  • Inspecting and subsetting data (base R and dplyr package)

  • Basic Data cleaning (handling missing values)

  • Export data

Dataset: MultiFactor_data.csv (Download the dataset from the blackboard).

Dataset structure:

Global change factors (treatments):

Column remark = treatment labels (CT = control, I = Insecticide, A = Antibiotic, P = PFAS, SU = Surfactant, H = Herbicide, S = Salinity, M = Microplastic, D = drought, C = Copper, FU = Fungicide, L = Lithium, N = Nitrogen deposition)

Soil response variables (measurements):

WSA (water stable aggregates), Decom (soil decomposition rate), PH (soil pH), actv_ace (N-acetyl-glucosaminidase activity), actv_cello (cellulase activity), actv_gluco (β-glucosidase activity), actv_phos (phosphatase activity).

1. Setup: working directory & packages

# install.packages("tidyverse")

# Load core packages
library(ggplot2)
library(dplyr)
library(tidyverse)

Setup your working directory. (create a folder ABV_course on your desktop, and set up you working directory to this folder) (also create R script files in the same folder)

Session -> Set Working Directory -> Choose Directory

Place the dataset MultiFactor_data.csv in your working file (working directory) and import the dataset into R.

Importing dataset

folder <- getwd()
data_file <- "MultiFactor_data.csv"
dat <- read.csv(file.path(folder, data_file))

Try other ways of importing

# Read the combined dataset (ensure the CSV file is in your working directory)
dat <- read.csv("MultiFactor_data.csv")

2. R language basics (10 minutes quick tour)

# Assignment
x <- 5
y <- c(1, 3, 5, 7)          # numeric vector
z <- c("CT","D","S")        # character vector

# Sequences and repetition
seq(0, 1, by = 0.2)
## [1] 0.0 0.2 0.4 0.6 0.8 1.0
rep("CT", 3)
## [1] "CT" "CT" "CT"
# Basic math
mean(y); sd(y); sum(y); length(y)
## [1] 4
## [1] 2.581989
## [1] 16
## [1] 4
# Logical comparisons & indexing
y > 3                    # logical vector
## [1] FALSE FALSE  TRUE  TRUE
y[y > 3]                 # filter values by condition
## [1] 5 7
# Missing values
v <- c(1, 2, NA, 4)
is.na(v)
## [1] FALSE FALSE  TRUE FALSE
mean(v, na.rm = TRUE)    # ignore NAs
## [1] 2.333333
# Lists & data frames
lst <- list(a = 1:3, b = c("x","y"))
df  <- data.frame(grp = c("CT","D","CT"), WSA = c(55, 48, 60))
str(df)
## 'data.frame':    3 obs. of  2 variables:
##  $ grp: chr  "CT" "D" "CT"
##  $ WSA: num  55 48 60

Rule of thumb: vectors are the basic building block; data frames/tibbles are just named columns of equal length.

3. Inspect the data

# Structure and column names
str(dat)

# Treatment codes present (e.g., "CT" control, "D" drought, etc.)
unique(dat$remark)

dim(dat)            # rows x cols
names(dat)          # column names
head(dat, 3)        # first 3 rows

Tip: If you want to rename your column, try this command: names(dat)[names(dat)=="remark"] <- "Treatment" (rename remark column as Treatment) Use Chat gpt to understand the command

4. Subset & merge (base R and dplyr command)

We’ll extract control (CT) and drought (D) treatment as a running example.

# Base R subsetting
control_data   <- dat[dat$remark == "CT", ]
treatment_data <- dat[dat$remark == "D", ]

# Merge two data frames vertically (same columns)
data_merg <- rbind(control_data, treatment_data)

Try other ways of subsetting (dplyr package)

data_merg <- dat %>%
  filter(remark %in% c("CT","D")) 

Select columns of interest

select_columns <- data_merg %>%
  select(remark, WSA, Decom, PH)

select_columns <- data_merg %>%
  select(6:8,22)

5. Basic cleaning & type fixes

Make remark a factor; ensure Lv is integer

dat <- dat %>%
  mutate(
    remark = factor(remark),
    Lv     = as.integer(Lv)
  )

Check missingness for key numeric variables

dat %>%
  summarise(across(c(WSA, Decom, PH, actv_ace), ~ sum(is.na(.x))))
##   WSA Decom PH actv_ace
## 1   6    10  2       49

Handling missing values

# Drop rows with missing WSA for a specific analysis
dat_wsa <- dat %>% drop_na(WSA)

# Impute NA with mean 
dat_imp <- dat %>%
  mutate(WSA_imp = if_else(is.na(WSA), mean(WSA, na.rm = TRUE), WSA))

6. Write data to disk

# CSV
write_csv(dat_imp, file.path(folder, "CombinedData_cleaned.csv"))