# HG changeset patch # User ecology # Date 1748427136 0 # Node ID 4da00cf0271994b60ffb0ab5e45302b2c6171dad planemo upload for repository https://github.com/jeanlecras/tools-ecology/tree/master/tools/WormsMeasurements commit ced658540f05bb07e1e687af30a3fa4ea8e4803c diff -r 000000000000 -r 4da00cf02719 test-data/enriched_data.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/enriched_data.tabular Wed May 28 10:12:16 2025 +0000 @@ -0,0 +1,11 @@ +"decimalLatitude" "decimalLongitude" "scientificName" "Development" "Fecundity" +-49.355 70.215 "Abatus cordatus" NA NA +-66.963303 163.223297 "Ctenocidaris spinosa" NA NA +-42.45 -74.75833333 "Loxechinus albus" NA NA +-37.606167 176.705167 "Ogmocidaris benhami" NA NA +-36.201698 175.834198 "Peronella hinemoae" NA NA +-37.494667 176.672501 "Phormosoma bursarium" NA NA +-43.469 173.572 "Pseudechinus huttoni" NA NA +-47.7 179.45 "Pseudechinus novaezealandiae" NA NA +-74.72 164.2183333 "Sterechinus neumayeri" NA NA +-70.51166667 -8.801 "Sterechinus sp" NA NA diff -r 000000000000 -r 4da00cf02719 test-data/enriched_data_inherited.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/enriched_data_inherited.tabular Wed May 28 10:12:16 2025 +0000 @@ -0,0 +1,11 @@ +"decimalLatitude" "decimalLongitude" "scientificName" "Development" "Fecundity" +-49.355 70.215 "Abatus cordatus" "planktotrophic" NA +-66.963303 163.223297 "Ctenocidaris spinosa" "direct development" NA +-42.45 -74.75833333 "Loxechinus albus" "planktotrophic" NA +-37.606167 176.705167 "Ogmocidaris benhami" "planktotrophic" NA +-36.201698 175.834198 "Peronella hinemoae" "planktotrophic" NA +-37.494667 176.672501 "Phormosoma bursarium" "planktotrophic" NA +-43.469 173.572 "Pseudechinus huttoni" "planktotrophic" NA +-47.7 179.45 "Pseudechinus novaezealandiae" "planktotrophic" NA +-74.72 164.2183333 "Sterechinus neumayeri" "planktotrophic" NA +-70.51166667 -8.801 "Sterechinus sp" NA NA diff -r 000000000000 -r 4da00cf02719 test-data/enriched_data_inherited_ohe.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/enriched_data_inherited_ohe.tabular Wed May 28 10:12:16 2025 +0000 @@ -0,0 +1,11 @@ +"decimalLatitude" "decimalLongitude" "scientificName" "Fecundity" "Development_direct development" "Development_planktotrophic" +-49.355 70.215 "Abatus cordatus" NA 0 1 +-66.963303 163.223297 "Ctenocidaris spinosa" NA 1 0 +-42.45 -74.75833333 "Loxechinus albus" NA 0 1 +-37.606167 176.705167 "Ogmocidaris benhami" NA 0 1 +-36.201698 175.834198 "Peronella hinemoae" NA 0 1 +-37.494667 176.672501 "Phormosoma bursarium" NA 0 1 +-43.469 173.572 "Pseudechinus huttoni" NA 0 1 +-47.7 179.45 "Pseudechinus novaezealandiae" NA 0 1 +-74.72 164.2183333 "Sterechinus neumayeri" NA 0 1 +-70.51166667 -8.801 "Sterechinus sp" NA NA NA diff -r 000000000000 -r 4da00cf02719 test-data/sample.tabular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-data/sample.tabular Wed May 28 10:12:16 2025 +0000 @@ -0,0 +1,11 @@ +"decimalLatitude" "decimalLongitude" "scientificName" +-66.963303 163.223297 "Ctenocidaris spinosa" +-70.51166667 -8.801 "Sterechinus sp" +-37.494667 176.672501 "Phormosoma bursarium" +-37.606167 176.705167 "Ogmocidaris benhami" +-74.72 164.2183333 "Sterechinus neumayeri" +-47.7 179.45 "Pseudechinus novaezealandiae" +-49.355 70.215 "Abatus cordatus" +-36.201698 175.834198 "Peronella hinemoae" +-43.469 173.572 "Pseudechinus huttoni" +-42.45 -74.75833333 "Loxechinus albus" diff -r 000000000000 -r 4da00cf02719 wormsmeasurements.R --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wormsmeasurements.R Wed May 28 10:12:16 2025 +0000 @@ -0,0 +1,131 @@ +##05/05/2025 +##Jean Le Cras +### Enrich dataset with data from WoRMS + +#load libraries +library(tidyverse) +library(worrms) +library(fastDummies) + +### parameters +args <- commandArgs(trailingOnly = TRUE) +if (length(args) == 0) { + stop("This tool needs at least one argument") +} + +scientificName_name <- args[3] +occurrence <- read.csv(args[1], header=T, sep="\t") %>% + arrange(.[[scientificName_name]]) +measurement_types <- unlist(str_split(args[2], ",")) +include_inherited <- ifelse(args[4]=="true", T, F) +pivot_wider <- ifelse(args[5]=="true", T, F) +exclude_NA <- ifelse(args[6]=="true", T, F) + +# regex to only keep genus and specific epithet from scientific names +regex_find <- "^([A-Z][^A-Z(]+)(.*)$" +regex_replace <- "\\1" + + +# function to extract the measurement values from the attributes data tibble +extract_traits_values <- function(traits_data) { + result <- setNames(rep(NA, length(measurement_types)), measurement_types) + + if (is.null(traits_data) || nrow(traits_data) == 0) { + return(result) + } + + traits_filtered <- traits_data %>% + filter(measurementType %in% measurement_types) %>% + filter(!is.na(measurementValue)) + + if (nrow(traits_filtered) == 0) { + return(result) + } + + for (i in 1:nrow(traits_filtered)) { + result[traits_filtered$measurementType[i]] <- traits_filtered$measurementValue[i] + } + return(result) +} + +# function to call the call the WoRMS API and get the measurement values +get_life_history_traits <- function(scientific_name) { + clean_scientific_name <- trimws(gsub(regex_find, regex_replace, scientific_name)) + + if (clean_scientific_name %in% names(cache)) { + return(cache[[clean_scientific_name]]) + } + + worms_id <- tryCatch( + wm_name2id(name = clean_scientific_name), + error = function(e) NA + ) + + if (is.na(worms_id) || length(worms_id) == 0) { + cache[[clean_scientific_name]] <<- NULL + return(NULL) + } + + data_attr <- tryCatch( + wm_attr_data(worms_id, include_inherited=include_inherited), + error = function(e) NULL + ) + + if (is.null(data_attr)) { + cache[[clean_scientific_name]] <<- NULL + return(NULL) + } + + traits <- extract_traits_values(data_attr) + cache[[clean_scientific_name]] <<- traits + return(traits) +} + +# a cache to limit API calls +cache <- list() + +# add a columns conataining the lists of values of the measurments requested +trait_data <- occurrence %>% + mutate(life_history_traits = map(.data[[scientificName_name]], ~ get_life_history_traits(.x))) + +# convert the column of lists to multiple columns of unique values +trait_data <- trait_data %>% + unnest_wider(life_history_traits) + +# make sur each measurement type has a column +for (col in measurement_types) { + if (!(col %in% names(trait_data))) { + trait_data[[col]] <- NA + } +} + +# list of quantitativ measurements +numeric_cols <- c() + +# try to convert columns to numeric and remember them +trait_data <- trait_data %>% + mutate(across(all_of(measurement_types), ~ { + numeric_col <- suppressWarnings(as.numeric(.)) + if (all(is.na(.) == is.na(numeric_col))) { + numeric_cols <<- c(numeric_cols, cur_column()) + numeric_col + } else { + . + } + })) + +# filter NA but only in the added columns +if (exclude_NA) { + trait_data <- trait_data[complete.cases(trait_data[, measurement_types]),] +} + +# determine what are the qualitativ columns to be one hot encoded +factor_cols <- setdiff(measurement_types, numeric_cols) + +# one hot encode quantitativ columns +if (pivot_wider & length(factor_cols) > 0) { + trait_data <- dummy_cols(trait_data, select_columns = factor_cols, remove_selected_columns=T, ignore_na=T) +} + +# write the enriched dataset as tabular +write.table(trait_data, "enriched_data.tabular", sep="\t", row.names = FALSE) \ No newline at end of file diff -r 000000000000 -r 4da00cf02719 wormsmeasurements.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wormsmeasurements.xml Wed May 28 10:12:16 2025 +0000 @@ -0,0 +1,127 @@ + + Enrich dataset with measurement type data from WoRMS + + + r-base + r-worrms + r-dplyr + r-tidyverse + r-fastDummies + + + + + + + + + + .+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.32614/CRAN.package.dplyr + 10.32614/CRAN.package.tidyverse + 10.32614/CRAN.package.worrms + 10.32614/CRAN.package.fastDummies + +