## ----setup, include = FALSE--------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ## ----va-engine, echo = FALSE, results = "asis", eval = TRUE------------------- cat(' ') ## ----------------------------------------------------------------------------- # library(taxify) ## ----------------------------------------------------------------------------- # field_names <- c( # "Quercus robur L.", # authorship to strip # "Quercus robus", # typo # "cf. Betula pendula", # field qualifier # "FAGUS SYLVATICA", # caps # "Quercus pedunculata", # historical synonym of Q. robur # "Q. petraea", # abbreviated genus # "Pinus abies", # synonym of Picea abies (a different genus) # "Festuca rubrra", # typo # "Fallopia japonica", # synonym of Reynoutria japonica (invasive) # "Taraxacum officinale" # ) # # res <- taxify(field_names) # res[, c("input_name", "accepted_name", "family", # "is_synonym", "match_type", "fuzzy_dist")] ## ----pipe-anim, echo = FALSE, results = "asis", eval = TRUE------------------- body <- " var s=VA.setup('pp-cv'); if(!s)return; var x=s.ctx,W=s.w,H=s.h,C=VA.C; var N=NM.length; var labs=['input','clean','match','resolve','accepted']; var SX=[64,232,420,602,786]; var yTrack=176; var PER_NAME=4.2,PERIOD=N*PER_NAME; function chip(cx,cy,txt,col,w){x.font=VA.F(12);var tw=x.measureText(txt).width;var hw=(w||Math.max(70,tw+16))/2;hw=Math.min(hw,(W-12)/2);cx=VA.clamp(cx,hw+6,W-hw-6);x.save();VA.glow(x,col,9);x.fillStyle=C.bg;x.strokeStyle=col;x.lineWidth=2;x.beginPath();x.rect(cx-hw,cy-15,hw*2,30);x.fill();x.stroke();VA.noglow(x);x.fillStyle=C.ink;x.textAlign='center';x.textBaseline='middle';x.fillText(txt,cx,cy);x.restore();x.textBaseline='alphabetic';} function station(i,active,col,sub){var cx=SX[i];x.strokeStyle=active?col:C.off;x.lineWidth=active?2:1;if(active)VA.glow(x,col,8);x.beginPath();x.arc(cx,yTrack,11,0,6.2832);x.stroke();VA.noglow(x);if(active){x.fillStyle=col;x.beginPath();x.arc(cx,yTrack,4,0,6.2832);x.fill();}x.fillStyle=active?C.ink:C.mut;x.font=VA.F(12,active);x.textAlign='center';x.fillText(labs[i],cx,yTrack+34);if(sub){x.fillStyle=col;x.font=VA.F(11);x.fillText(sub,cx,yTrack+50);}} function draw(tc){VA.bg(x,W,H); VA.glow(x,C.cyan,7);x.fillStyle=C.cyan;x.textAlign='left';x.font=VA.F(15,true);x.fillText('ONE NAME THROUGH THE PIPELINE',16,28);VA.noglow(x); var gi=Math.min(N-1,Math.floor(tc/PER_NAME));var lt=(tc-gi*PER_NAME)/PER_NAME; var isSyn=SYN[gi]===1;var isNone=MT[gi]==='none'; x.strokeStyle=C.grid;x.lineWidth=2;x.beginPath();x.moveTo(SX[0],yTrack);x.lineTo(SX[4],yTrack);x.stroke(); var seg=VA.clamp(lt/0.5,0,1)*4;var here=Math.floor(seg+0.0001); for(var i=0;i<5;i++){ var reached=i<=here; var col=C.cyan;var sub=null; if(i===1){col=C.amber;sub=reached?CLN[gi]:null;} if(i===2){col=isNone?C.red:C.green;sub=reached?MAT[gi]:null;} if(i===3){col=C.purple;sub=reached?(isSyn?'synonym':'already accepted'):null;if(!isSyn)col=C.off;} if(i===4){col=isNone?C.red:C.green;} station(i,reached,col,sub); } var a=Math.min(3,Math.floor(seg)),f=VA.clamp(seg-a,0,1); var px=VA.lerp(SX[a],SX[a+1],VA.easeOut(f)); if(lt<0.5) chip(px,yTrack-46,NM[gi],isNone?C.red:C.cyan); x.fillStyle=C.mut;x.font=VA.F(12);x.textAlign='center';x.fillText('input',SX[0],yTrack-86); x.fillStyle=isNone?C.red:C.green;x.font=VA.F(12,true);x.fillText(isNone?'unmatched':'accepted name',SX[4],yTrack-86); if(lt>=0.5){var aa=VA.clamp((lt-0.5)/0.2,0,1);x.globalAlpha=aa;chip(SX[4],yTrack-46,ACC[gi],isNone?C.red:C.green);x.globalAlpha=1;} var dotw=12;for(var k=0;k\n", "\n")) ## ----block-anim, echo = FALSE, results = "asis", eval = TRUE------------------ body <- " var s=VA.setup('bl-cv'); if(!s)return; var x=s.ctx,W=s.w,H=s.h,C=VA.C; var GX=16,GY=64,COLS=44,ROWS=22,TW=13,TH=15,GW=COLS*TW,GH=ROWS*TH; var bc0=8,bc1=15,br0=7,br1=13; var winC=12,winR=10; var GGX=GX+GW+44,GGW=64,GGY=64,GGH=GH; var T1=4.8,H1=2.0,T2=5.9,H2=3.4,CYCLE=T1+H1+T2+H2; function inBlock(c,r){return c>=bc0&&c<=bc1&&r>=br0&&r<=br1;} function tile(c,r,col,a){x.globalAlpha=a;x.fillStyle=col;x.fillRect(GX+c*TW,GY+r*TH,TW-1.4,TH-1.4);x.globalAlpha=1;} function frame(){VA.glow(x,C.cyan,6);x.strokeStyle=C.cyan;x.strokeRect(GX,GY,GW,GH);VA.noglow(x);} function blockOutline(){VA.glow(x,C.green,10);x.strokeStyle=C.green;x.lineWidth=2;x.strokeRect(GX+bc0*TW-1,GY+br0*TH-1,(bc1-bc0+1)*TW,(br1-br0+1)*TH);x.lineWidth=1;VA.noglow(x);} function gauge(frac,col,ghost,pct){x.strokeStyle=C.mut;x.strokeRect(GGX,GGY,GGW,GGH);var h=Math.max(frac>0?2:0,frac*GGH);VA.glow(x,col,8);x.fillStyle=col;x.fillRect(GGX+1,GGY+GGH-h,GGW-2,h);VA.noglow(x);if(ghost){x.strokeStyle=C.red;x.setLineDash([5,4]);x.lineWidth=1.5;x.beginPath();x.moveTo(GGX-4,GGY+2);x.lineTo(GGX+GGW+4,GGY+2);x.stroke();x.setLineDash([]);x.lineWidth=1;x.fillStyle=C.red;x.font=VA.F(11);x.textAlign='left';x.fillText('whole backbone',GGX-6,GGY-10);}x.fillStyle=C.ink;x.font=VA.F(14,true);x.textAlign='center';x.fillText(pct,GGX+GGW/2,GGY+GGH+20);x.fillStyle=C.mut;x.font=VA.F(11);x.fillText('names scored',GGX+GGW/2,GGY+GGH+36);} function header(t,col){x.textAlign='left';VA.glow(x,C.cyan,7);x.fillStyle=C.cyan;x.font=VA.F(15,true);x.fillText('FUZZY MATCH :: Quercus robus',16,26);VA.noglow(x);x.fillStyle=col;x.font=VA.F(13);x.fillText(t,16,46);} function draw(tc){VA.bg(x,W,H); var c,r; if(tc0.7){VA.glow(x,'#fff',10);x.fillStyle='#fff';x.fillRect(GX+winC*TW,GY+winR*TH,TW-1.4,TH-1.4);VA.noglow(x);} gauge(0.06,C.green,true,'one genus'); header('genus-blocked: scored only against other Quercus',C.green); } else { for(r=0;r '+QACC+' (1 edit, dist '+QD+')',GX,GY+GH+24); gauge(0.06,C.green,true,'one genus'); header('match found inside the block',C.green); } VA.scan(x,W,H); } VA.run(draw,CYCLE,null,'bl','bl-cv'); " cat(paste0( "\n", "\n")) ## ----------------------------------------------------------------------------- # summary(res) ## ----benchmark-anim, echo = FALSE, results = "asis", eval = TRUE-------------- body <- " var s=VA.setup('sp-cv'); if(!s)return; var x=s.ctx,W=s.w,H=s.h,C=VA.C; var BX=150,BW=W-150-150,b1=96,b2=190,bh=46; var PERIOD=17,HOLD=4; function fmt(sec){if(sec<60)return sec.toFixed(1)+' s';var m=sec/60;return sec.toFixed(0)+' s ('+m.toFixed(0)+' min)';} function bar(y,frac,col,name,done,lab){ x.fillStyle=C.off;x.fillRect(BX,y,BW,bh); var w=Math.max(frac>0?3:0,frac*BW); if(done)VA.glow(x,col,10);x.fillStyle=col;x.fillRect(BX,y,w,bh);VA.noglow(x); x.strokeStyle=C.grid;x.strokeRect(BX,y,BW,bh); x.fillStyle=C.ink;x.font=VA.F(14,true);x.textAlign='right';x.fillText(name,BX-12,y+bh/2+5); x.fillStyle=done?col:C.mut;x.font=VA.F(13,true);x.textAlign='left';x.fillText(lab,BX+w+12,y+bh/2+5); } function draw(tc){VA.bg(x,W,H); VA.glow(x,C.cyan,7);x.fillStyle=C.cyan;x.textAlign='left';x.font=VA.F(15,true);x.fillText('FUZZY MATCH :: 1,000 NAMES',16,28);VA.noglow(x); var run=Math.min(tc,PERIOD-HOLD);var prog=run/(PERIOD-HOLD); var simSec=prog*WFO; var taxDone=simSec>=TAX; var taxFrac=taxDone?1:simSec/TAX; var wfoFrac=Math.min(1,simSec/WFO); bar(b1,taxFrac,C.green,'taxify',taxDone,taxDone?fmt(TAX):''); bar(b2,wfoFrac,C.red,'WorldFlora',wfoFrac>=1,wfoFrac>=1?fmt(WFO):fmt(simSec)); x.fillStyle=C.mut;x.font=VA.F(12);x.textAlign='left';x.fillText('elapsed (simulated): '+fmt(simSec),BX,b2+bh+22); if(taxDone&&tc>PERIOD-HOLD-0.01){var aa=VA.clamp((tc-(PERIOD-HOLD))/1.0,0,1);x.globalAlpha=aa;VA.glow(x,C.green,8);x.fillStyle=C.green;x.font=VA.F(20,true);x.textAlign='center';x.fillText(Math.round(WFO/TAX)+'x faster',W/2,H-40);VA.noglow(x);x.globalAlpha=1;} VA.scan(x,W,H); } VA.run(draw,PERIOD,null,'sp','sp-cv'); " cat(paste0( "\n", "\n")) ## ----------------------------------------------------------------------------- # my_traits <- data.frame( # species = c("Quercus pedunculata", # synonym of Q. robur # "Pinus sylvestris", # "Betula pendula"), # seed_mass_mg = c(3200, 7.5, 0.2) # ) # # taxify(c("Quercus robur", "Pinus sylvestris", "Betula pendula")) |> # add_data(my_traits, species_col = "species") ## ----enrich-anim, echo = FALSE, results = "asis", eval = TRUE----------------- con_data <- "var G=[ {n:'Plants',s:'Plants',c:'#6bcb77',L:[['add_zanne()','woody / herbaceous'],['add_eive()','EIVE indicator values'],['add_diaz_traits()','seed mass & height'],['add_leda()','LEDA life-history'],['add_wcvp()','native range'],['add_glonaf()','naturalized alien flora'],['add_baseflor()','ecological traits'],['add_ecoflora()','British flora'],['add_floraweb()','German flora'],['add_pignatti()','Italian indicator values'],['add_fungalroot()','mycorrhizal type']]}, {n:'Birds & mammals',s:'Birds/mammals',c:'#3ad7ff',L:[['add_avonet()','bird morphology'],['add_elton_traits()','diet & body mass'],['add_pantheria()','mammal life-history']]}, {n:'Amphibians & reptiles',s:'Amph & reptiles',c:'#b388ff',L:[['add_amphibio()','amphibian traits'],['add_repttraits()','reptile traits & range']]}, {n:'Fish',s:'Fish',c:'#4d96ff',L:[['add_fishmorph()','morphology'],['add_fishbase()','ecology']]}, {n:'Arthropods',s:'Arthropods',c:'#ff8fd0',L:[['add_arthropod_traits()','arthropod traits'],['add_leptraits()','butterfly traits']]}, {n:'Fungi',s:'Fungi',c:'#ffd93d',L:[['add_fungal_traits()','fungal traits'],['add_funguild()','trophic guild']]}, {n:'Algae',s:'Algae',c:'#33ffd0',L:[['add_algae_traits()','algal traits']]}, {n:'Cross-taxon animals',s:'Cross-taxon',c:'#ffc24b',L:[['add_animaltraits()','body mass & metabolism'],['add_anage()','longevity & ageing']]}, {n:'Status, alien & names',s:'Status & alien',c:'#ff3b6b',L:[['add_iucn()','IUCN Red List'],['add_griis()','GRIIS invasive'],['add_alien_first_records()','first-record years'],['add_common_names()','vernacular names']]} ]; " body <- " var s=VA.setup('en-cv'); if(!s)return; var x=s.ctx,W=s.w,H=s.h,C=VA.C; var NG=G.length; var cx=280,cy=298,R=192; var px0=556,pw=W-556-12; var nLayers=0;for(var gi=0;gi=cy;var ly=n.y+(below?rad+15:-rad-8);x.fillText(G[i].s,n.x,ly);x.fillStyle=foc?G[i].c:C.mut;x.font=VA.F(10);x.fillText('('+G[i].L.length+')',n.x,ly+(below?13:-13));} function travel(i,t){var n=node(i);var u=t-Math.floor(t);var tx=VA.lerp(n.x,cx,VA.easeOut(u)),ty=VA.lerp(n.y,cy,VA.easeOut(u));VA.glow(x,G[i].c,8);x.fillStyle=G[i].c;x.beginPath();x.arc(tx,ty,3.6,0,6.2832);x.fill();VA.noglow(x);} function panel(i,lt){var g=G[i];x.textAlign='left';VA.glow(x,g.c,8);x.fillStyle=g.c;x.font=VA.F(15,true);x.fillText(g.n,px0,92);VA.noglow(x);x.strokeStyle=g.c;x.lineWidth=2;x.beginPath();x.moveTo(px0,102);x.lineTo(px0+pw,102);x.stroke();x.lineWidth=1;for(var k=0;k\n", "\n")) ## ----------------------------------------------------------------------------- # field <- c( # "Quercus petraea", "Pinus sylvestris", "Picea abies", "Betula pendula", # "Acer pseudoplatanus", "Acer platanoides", "Acer campestre", "Corylus avellana", # "Fraxinus excelsior", "Carpinus betulus", "Sorbus aucuparia", "Tilia cordata", # "Ulmus glabra", "Alnus glutinosa", "Salix caprea", "Populus tremula", # "Prunus avium", "Prunus spinosa", "Crataegus monogyna", "Sambucus nigra", # "Cornus sanguinea", "Viburnum opulus", "Euonymus europaeus", "Ligustrum vulgare", # "Frangula alnus", "Juniperus communis", "Taxus baccata", "Larix decidua", # "Abies alba", "Rosa canina", "Rubus idaeus", "Hedera helix", # "Clematis vitalba", "Berberis vulgaris", "Betula pubescens", "Prunus padus", # "Rhamnus cathartica", "Lonicera xylosteum", "Trifolium repens", "Trifolium pratense", # "Festuca ovina", "Dactylis glomerata", "Plantago lanceolata", "Plantago major", # "Plantago media", "Achillea millefolium", "Ranunculus acris", "Ranunculus repens", # "Urtica dioica", "Poa pratensis", "Poa annua", "Galium mollugo", # "Galium aparine", "Bellis perennis", "Cardamine pratensis", "Cirsium arvense", # "Cirsium vulgare", "Daucus carota", "Heracleum sphondylium", "Anthriscus sylvestris", # "Lotus corniculatus", "Medicago lupulina", "Vicia cracca", "Lathyrus pratensis", # "Stellaria media", "Silene dioica", "Silene vulgaris", "Geranium pratense", # "Geranium robertianum", "Glechoma hederacea", "Lamium album", "Prunella vulgaris", # "Ajuga reptans", "Veronica chamaedrys", "Rumex acetosa", "Rumex obtusifolius", # "Chenopodium album", "Capsella bursa-pastoris", "Senecio vulgaris", "Leucanthemum vulgare", # "Centaurea jacea", "Knautia arvensis", "Campanula rotundifolia", "Primula veris", # "Anemone nemorosa", "Filipendula ulmaria", "Lythrum salicaria", "Robinia pseudoacacia", # "Solidago canadensis", "Solidago gigantea", "Impatiens glandulifera", # "Heracleum mantegazzianum", "Prunus serotina", "Quercus rubra", # "Quercus robur L.", "FAGUS SYLVATICA", "Quercus robus", # "cf. Taraxacum officinale", "Quercus pedunculata", "Festuca rubrra" # ) # # dat <- taxify(field) |> # add_zanne() |> # add_eive() |> # add_diaz_traits() # # head(dat[, c("accepted_name", "woodiness", "eive_light", # "eive_reaction", "eive_nutrients", "plant_height_m")], 6) ## ----------------------------------------------------------------------------- # cor.test(dat$eive_reaction, dat$eive_nutrients)