Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Biodiversity data access, species occurrence, and ecological tools
.claude/skills/brycewang-stanford-biodiversity-data-guide/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 57% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 97% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 165% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 230% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 98% | 0% |
Access, analyze, and visualize biodiversity data from global databases including GBIF, iNaturalist, and GenBank for ecological and evolutionary research.
| Database | Content | Records | API | Cost | |----------|---------|---------|-----|------| | GBIF | Species occurrence records | 2.4B+ | Yes | Free | | iNaturalist | Citizen science observations | 180M+ | Yes | Free | | GenBank (NCBI) | Genetic sequences | 250M+ | Yes | Free | | BOLD Systems | DNA barcode records | 15M+ | Yes | Free | | eBird | Bird observations | 1.3B+ | Yes | Free | | IUCN Red List | Conservation status | 160,000+ | Yes | Free (with key) | | OBIS | Marine biodiversity | 100M+ | Yes | Free | | Catalogue of Life | Taxonomic backbone | 2M+ species | Yes | Free | | TRY Plant Trait | Plant functional traits | 12M+ | Request | Free | | WorldClim | Climate data (rasters) | Global | Download | Free |
pythonfrom pygbif import species as sp from pygbif import occurrences as occ # Search for a species by name name_result = sp.name_backbone(name="Panthera tigris", rank="species") taxon_key = name_result["usageKey"] print(f"GBIF taxon key: {taxon_key}") print(f"Status: {name_result['status']}") print(f"Kingdom: {name_result['kingdom']}") # Get occurrence records results = occ.search( taxonKey=taxon_key, hasCoordinate=True, # Only georeferenced records country="IN", # India limit=100, year="2020,2024", # Year range basisOfRecord="HUMAN_OBSERVATION" ) print(f"Total records matching: {results['count']}") for record in results["results"][:5]: print(f" [{record.get('year')}] {record.get('decimalLatitude'):.4f}, " f"{record.get('decimalLongitude'):.4f} - {record.get('datasetName', 'N/A')}")
rlibrary(rgbif) library(sf) library(ggplot2) # Get occurrence data tiger_key <- name_backbone(name = "Panthera tigris")$usageKey occurrences <- occ_search( taxonKey = tiger_key, hasCoordinate = TRUE, limit = 500, year = "2020,2024", basisOfRecord = "HUMAN_OBSERVATION" ) # Convert to spatial data occ_df <- occurrences$data coords <- occ_df[, c("decimalLongitude", "decimalLatitude")] occ_sf <- st_as_sf(coords, coords = c("decimalLongitude", "decimalLatitude"), crs = 4326) # Map occurrences world <- rnaturalearth::ne_countries(scale = "medium", returnclass = "sf") ggplot() + geom_sf(data = world, fill = "grey90") + geom_sf(data = occ_sf, color = "red", size = 1, alpha = 0.5) + coord_sf(xlim = c(60, 150), ylim = c(-10, 50)) + labs(title = "Panthera tigris occurrences (2020-2024)") + theme_minimal() ggsave("tiger_map.pdf", width = 10, height = 6)
rlibrary(dismo) library(raster) # 1. Get occurrence data occ_data <- occ_search(taxonKey = tiger_key, hasCoordinate = TRUE, limit = 1000)$data occ_points <- occ_data[, c("decimalLongitude", "decimalLatitude")] occ_points <- na.omit(occ_points) # 2. Get environmental predictors (WorldClim bioclimatic variables) bioclim <- getData("worldclim", var = "bio", res = 10) # bio1 = Annual Mean Temperature # bio12 = Annual Precipitation # bio4 = Temperature Seasonality # ... (19 bioclimatic variables total) # 3. Extract environmental values at occurrence points env_values <- extract(bioclim, occ_points) # 4. Generate background (pseudo-absence) points bg_points <- randomPoints(bioclim, n = 10000) # 5. Fit MaxEnt model me_model <- maxent(bioclim, occ_points, a = bg_points, args = c("betamultiplier=1.5", "responsecurves=true")) # 6. Predict habitat suitability prediction <- predict(me_model, bioclim) plot(prediction, main = "Predicted Habitat Suitability") points(occ_points, pch = 16, cex = 0.5) # 7. Evaluate model eval_result <- evaluate(me_model, p = occ_points, a = bg_points, x = bioclim) print(paste("AUC:", round(eval_result@auc, 3)))
rlibrary(ape) library(phytools) # Read alignment (FASTA format) alignment <- read.FASTA("aligned_sequences.fasta") # Distance-based tree (Neighbor-Joining) dist_matrix <- dist.dna(alignment, model = "TN93") nj_tree <- nj(dist_matrix) # Root the tree rooted_tree <- root(nj_tree, outgroup = "outgroup_species") # Plot phylogeny plot(rooted_tree, type = "phylogram", cex = 0.8) axisPhylo() # Maximum likelihood tree (using phangorn) library(phangorn) data_phyDat <- phyDat(alignment, type = "DNA") ml_tree <- pml_bb(data_phyDat, model = "GTR+G+I", rearrangement = "NNI")
rlibrary(caper) # Phylogenetic independent contrasts # Test whether body mass predicts home range size # while accounting for phylogenetic relatedness trait_data <- data.frame( species = c("Sp_A", "Sp_B", "Sp_C", "Sp_D"), body_mass = c(5.2, 12.1, 3.8, 45.0), home_range = c(10, 25, 8, 120) ) # Create comparative data object comp_data <- comparative.data( phy = rooted_tree, data = trait_data, names.col = species, vcv = TRUE ) # Phylogenetic Generalized Least Squares (PGLS) pgls_model <- pgls(log(home_range) ~ log(body_mass), data = comp_data, lambda = "ML") # Estimate Pagel's lambda summary(pgls_model)
pythonimport numpy as np from scipy.stats import entropy def calculate_diversity(abundance_vector): """Calculate common biodiversity metrics.""" n = np.array(abundance_vector) N = n.sum() p = n / N # Relative abundances p = p[p > 0] # Remove zeros return { "species_richness": len(n[n > 0]), "shannon_H": entropy(p, base=np.e), "simpson_D": 1 - np.sum(p**2), "evenness_J": entropy(p, base=np.e) / np.log(len(p)), "fisher_alpha": estimate_fisher_alpha(n), "total_abundance": int(N) } def estimate_fisher_alpha(n): """Estimate Fisher's alpha diversity parameter.""" from scipy.optimize import brentq S = len(n[n > 0]) N = n.sum() def equation(alpha): return alpha * np.log(1 + N/alpha) - S try: return brentq(equation, 0.1, 1000) except ValueError: return np.nan # Example: Bird community survey abundances = [45, 23, 12, 8, 5, 3, 2, 1, 1] metrics = calculate_diversity(abundances) for key, val in metrics.items(): print(f" {key}: {val:.4f}" if isinstance(val, float) else f" {key}: {val}")
rlibrary(vegan) # Species abundance matrix (sites x species) community <- matrix(c( 10, 5, 3, 0, 1, 8, 12, 0, 2, 3, 0, 1, 15, 8, 0, 2, 0, 12, 10, 1 ), nrow = 4, byrow = TRUE, dimnames = list(paste0("Site", 1:4), paste0("Sp", 1:5))) # Alpha diversity diversity(community, index = "shannon") # Shannon H diversity(community, index = "simpson") # Simpson 1-D # Beta diversity (Bray-Curtis dissimilarity) bc_dist <- vegdist(community, method = "bray") # NMDS ordination nmds <- metaMDS(community, distance = "bray", k = 2) plot(nmds, type = "t") # PERMANOVA (testing group differences) env_data <- data.frame(habitat = c("forest", "forest", "grassland", "grassland")) adonis2(community ~ habitat, data = env_data, method = "bray")
Darwin Core (DwC) is the standard schema for biodiversity data exchange:
| Term | Description | Example | |------|-------------|---------| | scientificName | Full taxonomic name | "Panthera tigris (Linnaeus, 1758)" | | decimalLatitude | Latitude in decimal degrees | 27.1751 | | decimalLongitude | Longitude in decimal degrees | 78.0421 | | eventDate | Date of observation | "2024-03-15" | | basisOfRecord | Type of record | "HUMAN_OBSERVATION" | | coordinateUncertaintyInMeters | Spatial precision | 100 | | institutionCode | Data provider | "iNaturalist" |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 16,972 | 12,679 | -25% | 1 | 1 | 0% | 3,283 | 5,166 | +57% | 0 | 0 | — |
case-02 | fail→fail | 23,261 | 20,486 | -12% | 1 | 1 | 0% | 4,086 | 6,368 | +56% | 0 | 0 | — |
case-03 | fail→fail | 19,930 | 14,640 | -27% | 1 | 1 | 0% | 3,638 | 5,944 | +63% | 0 | 0 | — |
case-04 | pass→pass | 15,982 | 16,552 | +4% | 1 | 1 | 0% | 3,055 | 6,061 | +98% | 0 | 0 | — |
case-05 | pass→pass | 11,574 | 12,609 | +9% | 1 | 1 | 0% | 2,195 | 4,763 | +117% | 0 | 0 | — |
case-06 | fail→fail | 13,561 | 16,814 | +24% | 1 | 1 | 0% | 2,461 | 5,652 | +130% | 0 | 0 | — |
case-07 | pass→pass | 14,460 | 12,014 | -17% | 1 | 1 | 0% | 2,580 | 4,955 | +92% | 0 | 0 | — |
case-08 | pass→pass | 16,384 | 21,323 | +30% | 1 | 1 | 0% | 3,297 | 6,734 | +104% | 0 | 0 | — |
case-09 | pass→pass | 13,083 | 11,886 | -9% | 1 | 1 | 0% | 2,563 | 4,622 | +80% | 0 | 0 | — |
case-10 | fail→pass | 15,035 | 18,300 | +22% | 1 | 1 | 0% | 2,854 | 5,615 | +97% | 0 | 0 | — |
case-16 | pass→pass | 30,455 | 13,018 | -57% | 1 | 1 | 0% | 4,814 | 5,038 | +5% | 0 | 0 | — |
case-11 | fail→fail | 17,055 | 19,493 | +14% | 1 | 1 | 0% | 3,267 | 6,519 | +100% | 0 | 0 | — |
case-12 | pass→pass | 12,236 | 11,240 | -8% | 1 | 1 | 0% | 2,346 | 4,823 | +106% | 0 | 0 | — |
case-13 | fail→pass | 8,181 | 11,647 | +42% | 1 | 1 | 0% | 1,650 | 4,376 | +165% | 0 | 0 | — |
case-14 | pass→pass | 8,983 | 7,743 | -14% | 1 | 1 | 0% | 1,736 | 4,232 | +144% | 0 | 0 | — |
case-15 | pass→pass | 15,662 | 14,126 | -10% | 1 | 1 | 0% | 2,642 | 5,160 | +95% | 0 | 0 | — |
case-17 | pass→pass | 7,852 | 7,202 | -8% | 1 | 1 | 0% | 1,438 | 4,089 | +184% | 0 | 0 | — |
case-18 | fail→pass | 5,966 | 7,020 | +18% | 1 | 1 | 0% | 1,189 | 3,918 | +230% | 0 | 0 | — |
case-19 | pass→pass | 7,228 | 5,213 | -28% | 1 | 1 | 0% | 1,216 | 3,724 | +206% | 0 | 0 | — |
case-20 | fail→fail | 13,262 | 11,916 | -10% | 1 | 1 | 0% | 2,190 | 4,912 | +124% | 0 | 0 | — |
case-21 | pass→pass | 6,088 | 10,080 | +66% | 1 | 1 | 0% | 1,017 | 4,555 | +348% | 0 | 0 | — |
case-22 | pass→pass | 14,374 | 10,486 | -27% | 1 | 1 | 0% | 2,679 | 4,961 | +85% | 0 | 0 | — |
case-23 | fail→fail | 8,966 | 8,529 | -5% | 1 | 1 | 0% | 1,843 | 4,460 | +142% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +17 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.