############################################################ ### R BASICS WORKSHOP ### ### PRESENTATION 3.2: MAIN CLASSES OF OBJECTS ### ### ### ### Center for Conservation and Sustainable Development ### ### Missouri Botanical Garden ### ### Website: rbasicsworkshop.weebly.com ### ### Last modification: 2021-June-06 ### ############################################################ ### C. CLASSES OF OBJECTS ################################## ## IMPORTANT: The class of an object is an important ## determinant of how it behaves in R. ## Confusing classes is a common source of problems when ## programming! # 1. Vectors: 1 dimension - numeric, character or logical # 2. Factors: 1 dimension - levels of a categorical variable # 2. Matrices: 2 dimensions - rows by columns # 3. Arrays: n dimensions # 4. Data frames: 2 dimensions - observations by variables # 5. Lists # 6. Other classes: e.g. lm, phylo, shapefile, etc. ## IMPORTANT: Each object has ATTRIBUTES defining how it ## works in R. ## Common attributes include: class, length, dimensions, ## names, etc. ### A. SOME OBJECTS WE WILL NEED LATER ##################### # a. Let's suppose we have abundances of 5 species measured # in a forest plot in two different years (numeric # values). abund.t1 <- c(0, 17, 34, 26, 82) abund.t2 <- c(1, 17, 31, 27, 91) # b. Let's suppose, we also have the names of the species # (character data). spp <- c("I.ynga", "I.edulis", "I.macrophylla", "I.punctata", "I.alba") # c. Also, let's suppose we need a variable that indicate if # abundances have increased or not (logical values). increm <- c(TRUE, FALSE, FALSE, TRUE, TRUE) ### B. VECTORS ############################################ # Vectors represent a linear sequence of values. ## IMPORTANT: Each value in the sequence is an ELEMENT of ## the object. abund.t1 abund.t2 spp increm # CLASS is the main attribute of a vector class(abund.t1) class(spp) class(increm) # LENGTH is another fundamental attribute of a vector length(x = abund.t1) length(x = spp) length(x = increm) ## IMPORTANT: Vectors can ONLY have one main type of data: ## numeric, character or logical. NEVER A COMBINATION! x <- c(1,2,3) x class(x) x2 <- c(1,2,3, "a") x2 class(x2) ## However, NAs can be introduced with any of these types ## of data: x <- c(1,2,NA,3,NA) x class(x) ### C. FACTORS ############################################# # Factors also represent a linear sequence of values, but # are designed to be LEVELS of a categorical variable. # For example, suppose we have the phenological status of # several individual trees: pheno <- c("sterile", "sterile", "flowering", "fruiting", "sterile", "flowering", "flowering", "sterile") pheno length(pheno) class(pheno) mode(pheno) pheno2 <- factor(x = pheno) pheno2 length(pheno2) class(pheno2) mode(pheno2) identical(pheno, pheno2) # An important attribute of factors is their LEVELS levels(pheno2) # IMPORTANT: the class of an object commonly affects how # functions work with them. For example: plot(pheno) plot(pheno2) ### D. MATRICES ############################################ # Matrices are similar to vectors, but they have two # dimensions: ROWS AND COLUMNS. # Suppose we have abundances of 5 species of trees (columns) # in 3 different sites (rows): abund.M <- matrix(data = 1:(3*5), nrow = 3, ncol = 5) abund.M class(abund.M) # Let's use a little more realistic values of abundance abund.M <- matrix(data = rpois(n = 3*5, lambda = 10), nrow = 3, ncol = 5) abund.M # Like vectors, matrices have LENGTH which return the # number of elements length(abund.M) # In addition, matrices also have DIMENSIONS dim(abund.M) nrow(abund.M) ncol(abund.M) # In matrices, it is often useful to have NAMES for rows # and columns colnames(abund.M) rownames(abund.M) colnames(abund.M) <- spp rownames(abund.M) <- paste("site_", 1:nrow(abund.M), sep = "") abund.M ## IMPORTANT: Matrices, like vectors, can have ONLY one type ## of data: numeric or character or logical. NEVER A ## COMBINATION. abund.M2 <- matrix(sample(c(1:10, letters), 3*5), nrow = 3, ncol = 5) abund.M2 class(abund.M2) mode(abund.M2) spp abund.t1 abund.t2 mixed.matrix <- cbind(spp, abund.t1, abund.t2) mixed.matrix mode(mixed.matrix) ### E. ARRAYS ############################################## # Arrays are similar to matrices, but have MORE THAN TWO # DIMENSIONS. # With three dimensions, it's like having a cube of data. # Like multiple matrices of the same dimensions one behind # the another (aligned by rows and columns). abund.A <- array(data = 1:(3*5*2), dim = c(3,5,2)) abund.A # With a little more realistic values of abundance: abund.A <- array(data = rpois(3*5*2, 10), dim = c(3,5,2)) abund.A mode(abund.A) class(abund.A) length(abund.A) dim(abund.A) dimnames(abund.A) # We can give names to each element in each dimension dimnames(abund.A) <- list(paste("site_", 1:3, sep = ""), spp, c("2008", "2013")) abund.A ### F. DATA FRAMES ######################################### # Data frames organize measurements of variables (columns) # on study units (rows). Thus, in data frames EACH COLUMN # MAY BE OF a DIFFERENT TYPE (numeric, character, logical # or factors). abund.data <- data.frame(spp, abund.t1, abund.t2, increm) abund.data class(abund.data) # IMPORTANT: matrices and data frames behave differently! abund.data2 <- as.matrix(abund.data) abund.data2 class(abund.data2) dim(abund.data) dim(abund.data2) length(abund.data) length(abund.data2) mode(abund.data) mode(abund.data2) names(abund.data) names(abund.data2) plot(abund.data) plot(abund.data2) ### G. LISTS ############################################### # Lists can also contain elements of different types or # classes. Elements in a list DO NOT need to be of the same # length or dimensions. abund.M class(abund.M) pheno class(pheno) abund.data class(abund.data) random.list <- list(abund.M, pheno, abund.data) # Each object becomes an element of the list random.list # Some attributes of a list: class(random.list) length(random.list) dim(random.list) names(random.list) names(random.list) <- c("abund.M", "pheno", "abund.data") random.list # Understanding the structure of a list can be very useful: str(random.list) ## NOTE: Many functions use list-like objects to export ## results of analyses: x <- rnorm(100) y <- 4 + 5 * x + rnorm(100) plot(y ~ x) lm.res <- lm(y ~ x) lm.res str(lm.res) ### H. OTHER ############################################### # Many functions generate objects of particular classes. # However, the vast majority are modifications of the basic # objects that we revised. For example: # Linear models generate objects of class *lm*, but have # the structure of lists: class(lm.res) # However, being of class *lm* makes certain functions # handle this object in ways specific to its class. plot(lm.res) # Another object class are phylogenetic trees # (class *phylo*) install.packages("ape") # This installs a package # called *ape* library(ape) # This opens the package # The package *ape* contains a phylogenetic tree of bats data(chiroptera) # This opens the phylogenetic tree named # *chiroptera* class(chiroptera) # Despite being an object of class *phylo*, this object has # the structure of a list: str(chiroptera) # The function *plot* knows what to do when given a # phylogenetic tree plot(chiroptera, show.tip.label = FALSE)