R/ethnoChord.R

Defines functions ethnoChord

Documented in ethnoChord

#' Chord diagram of ethnobotany uses and species
#'
#' Creates a simple chord diagram of species and uses for ethnobotany studies. For more on the circlize package see Zuguang Gu's 'Circular Visualization in R' \url{https://jokergoo.github.io/circlize_book/book/}
#' @usage ethnoChord(data, by)
#' 
#' @references  
#' Gu, Zuguang, Lei Gu, Roland Eils, Matthias Schlesner, and Benedikt Brors. “Circlize Implements and Enhances Circular Visualization in R.” Bioinformatics, 2014, 393.
#' @references  
#' Whitney, C. W., Bahati, J., and Gebauer, J. (2018), Ethnobotany and agrobiodiversity; valuation of plants in the homegardens of southwestern Uganda. Ethnobiology Letters, 9(2), 90-100. \doi{10.14237/ebl.9.2.2018.503}
#' 
#' @param data is an ethnobotany data set with column 1 'informant' and 2 'sp_name' as row identifiers of informants and of species names respectively.
#' The rest of the columns are the identified ethnobotany use categories. The data should be populated with counts of uses per person (should be 0 or 1 values).
#' @param by indicates the variable that should be mapped to the bottom of the chord diagram. This automatically defaults to the column referring to the species (by = "sp_name")
#' 
#' @keywords graphs arith math logic methods misc survey
#' 
#' @return Chord diagram figure for each use by 'informant' (top half) related to each 'sp_name' (bottom half) in the data set. 
#' To change variable names try using the dplyr rename function.
#' 
#' @section Warning:
#' 
#' Identification for informants and species must be listed by the names 'informant' and 'sp_name' respectively in the data set.
#' The rest of the columns represent the identified ethnobotany use categories. These data should be populated with counts of uses per person (should be 0 or 1 values).
#' 
#' @importFrom circlize chordDiagram circos.text get.cell.meta.data
#' @importFrom dplyr filter rename select 
#' @importFrom graphics strwidth
#' @importFrom magrittr %>%
#' @importFrom reshape2 melt
#'
#' @examples
#' 
#' #Use built-in ethnobotany data example
#' ethnoChord(ethnobotanydata, by = "informant")
#' 
#' #Generate random dataset of three informants uses for four species
#' 
#' eb_data <- data.frame(replicate(10,sample(0:1,20,rep=TRUE)))
#' names(eb_data) <- gsub(x = names(eb_data), pattern = "X", replacement = "Use_")  
#' eb_data$informant <- sample(c('User_1', 'User_2', 'User_3'), 20, replace=TRUE)
#' eb_data$sp_name <- sample(c('sp_1', 'sp_2', 'sp_3', 'sp_4'), 20, replace=TRUE)
#' 
#' ethnoChord(eb_data, by = "informant")
#' 
#' @export ethnoChord
#' 
ethnoChord <- function(data, by = "sp_name") {
  
  #Add error stops ####
  #Check that packages are loaded
    {
  if (!requireNamespace("reshape2", quietly = TRUE)) {
        stop("Package \"reshape2\" needed for this function to work. Please install it.",
            call. = FALSE)
  }
  
  if (!requireNamespace("circlize", quietly = TRUE)) {
     stop("Package \"circlize\" needed for this function to work. Please install it.",
          call. = FALSE)
  }
  
  if (!requireNamespace("dplyr", quietly = TRUE)) {
    stop("Package \"dplyr\" needed for this function to work. Please install it.",
         call. = FALSE)
  }
  
  if (!requireNamespace("magrittr", quietly = TRUE)) {
    stop("Package \"magrittr\" needed for this function to work. Please install it.",
         call. = FALSE)
  }    
    }# end package loading check
  
  # Use 'complete.cases' from stats to get to the collection of obs without NA
  
    if (any(is.na(data))) {
      warning("Some of your observations included \"NA\" and were removed. Consider using \"0\" instead.")
    data<-data[stats::complete.cases(data), ]
    }# end error stops
  
      if (nrow(table(data$informant))>50) {
        warning("Your data has over 50 informants. This will be hard to fit on a plot. Consider using fewer or categorizing them instead.")
      }
  
      if (nrow(table(data$sp_name))>50) {
        warning("Your data has over 50 species. This will be hard to fit on a plot. Consider using fewer or categorizing them instead.")
      }
  
  # Set the variables to NULL first, appeasing R CMD check
  informant <- sp_name <- variable <- value <- strwidth <- NULL 
  
  # Melt ethnobotany data
  mat <- reshape2::melt(data, id=c("informant","sp_name")) %>% 
    dplyr::filter(value >=1)%>%
    #dplyr::arrange(by) %>%  
    dplyr::arrange(variable) %>% 
    dplyr::select(by, variable)
  
  # Create chord plot ####
  
  circlize::chordDiagram(mat, annotationTrack = "grid", 
                         preAllocateTracks = list(track.height = max(graphics::strwidth(unlist(dimnames(mat))))))
  circlize::circos.track(track.index = 1, panel.fun = function(x, y) {
    xlim = circlize::get.cell.meta.data("xlim")
    xplot = circlize::get.cell.meta.data("xplot")
    ylim = circlize::get.cell.meta.data("ylim")
    sector.name = circlize::get.cell.meta.data("sector.index")
    
    if(abs(xplot[2] - xplot[1]) < 20) {
      circlize::circos.text(mean(xlim), ylim[1], sector.name, facing = "clockwise",
                            niceFacing = TRUE, adj = c(0, 0.5), col = "black")
    } else {
      circlize::circos.text(mean(xlim), ylim[1], sector.name, facing = "clockwise",
                            niceFacing = TRUE, adj = c(0, 0.5), col = "black")
    }
  }, bg.border = NA)

}

Try the ethnobotanyR package in your browser

Any scripts or data that you put into this service are public.

ethnobotanyR documentation built on Dec. 28, 2022, 2:15 a.m.