1 Libraries needed

library(BiodiversityR)
library(ggplot2)
library(ggsci)
library(ggrepel)

2 Introduction

Someone recently asked me for some additional examples of analyzing Importance Value Index (IVI) values besides the examples provided with the documentation of the BiodiversityR::importancevalue function.

Here I show how the IVI can be analyzed through ordination analysis and with rank-abundance curves.

3 IFRI example data

The same data from the International Forestry Resources and Institutions network will be used as for the documentation of the function.

data(ifri)
summary(ifri)
##  forest        plotID        species        count            basal        
##  LOT:153   LOTP004: 11   Acersacc: 64   Min.   : 1.000   Min.   :   78.5  
##  MCF:166   YSFP021:  9   Lirituli: 38   1st Qu.: 1.000   1st Qu.:  349.6  
##  YSF:167   YSFP034:  9   Queralba: 34   Median : 2.000   Median :  889.7  
##            LOTP010:  8   Ulmurubr: 27   Mean   : 2.963   Mean   : 1630.1  
##            LOTP017:  8   Fraxamer: 26   3rd Qu.: 3.000   3rd Qu.: 2114.0  
##            LOTP026:  8   Caryovat: 22   Max.   :26.000   Max.   :12767.3  
##            (Other):433   (Other) :275
IV <- importancevalue(ifri, site='plotID', species='species', count='count', 
    basal='basal', factor='forest', level='YSF')
attributes(IV)
## $dim
## [1] 32  7
## 
## $dimnames
## $dimnames[[1]]
##  [1] "Queralba" "Acersacc" "Quervelu" "Lirituli" "Fagugran" "Acerrubr"
##  [7] "Querrubr" "Fraxamer" "Caryovat" "Querprin" "Juglnigr" "Sassalbi"
## [13] "Quermueh" "Pinustro" "Ulmuamer" "Caryglab" "Cornflor" "Ulmurubr"
## [19] "Fraxpenn" "Nysssylv" "Popugran" "Carylaci" "Carysp."  "Tiliamer"
## [25] "Carycord" "Castpumi" "Popuhete" "Aescglab" "Quercocc" "Quermich"
## [31] "Prunsero" "Platocci"
## 
## $dimnames[[2]]
## [1] "frequency"         "density"           "dominance"        
## [4] "frequency.percent" "density.percent"   "dominance.percent"
## [7] "importance.value"

These results can transformed to a data.frame directly

IV <- data.frame(IV)
summary(IV)
##    frequency          density        dominance       frequency.percent
##  Min.   :0.02778   Min.   : 1.00   Min.   :  116.9   Min.   : 0.5988  
##  1st Qu.:0.02778   1st Qu.: 1.00   1st Qu.:  605.6   1st Qu.: 0.5988  
##  Median :0.08333   Median : 4.00   Median : 1975.1   Median : 1.7964  
##  Mean   :0.14497   Mean   :11.38   Mean   : 9086.3   Mean   : 3.1250  
##  3rd Qu.:0.19444   3rd Qu.:11.00   3rd Qu.: 7679.3   3rd Qu.: 4.1916  
##  Max.   :0.75000   Max.   :78.00   Max.   :76368.6   Max.   :16.1677  
##  density.percent   dominance.percent importance.value 
##  Min.   : 0.2747   Min.   : 0.0402   Min.   : 0.9137  
##  1st Qu.: 0.2747   1st Qu.: 0.2083   1st Qu.: 1.3217  
##  Median : 1.0989   Median : 0.6793   Median : 3.7465  
##  Mean   : 3.1250   Mean   : 3.1250   Mean   : 9.3750  
##  3rd Qu.: 3.0220   3rd Qu.: 2.6411   3rd Qu.:10.1033  
##  Max.   :21.4286   Max.   :26.2651   Max.   :58.8949
head(IV)
##          frequency density dominance frequency.percent density.percent
## Queralba 0.5833333      73   76368.6         12.574850       20.054945
## Acersacc 0.7500000      78   26615.6         16.167665       21.428571
## Quervelu 0.3888889      43   61531.9          8.383234       11.813187
## Lirituli 0.2777778      14   24138.6          5.988024        3.846154
## Fagugran 0.3055556      20   14733.5          6.586826        5.494505
## Acerrubr 0.2777778      19    9772.3          5.988024        5.219780
##          dominance.percent importance.value
## Queralba         26.265077         58.89487
## Acersacc          9.153772         46.75001
## Quervelu         21.162364         41.35878
## Lirituli          8.301870         18.13605
## Fagugran          5.067220         17.14855
## Acerrubr          3.360939         14.56874

In the second example, importance values are calculated separately for the different types of forests

IV <- importancevalue.comp(ifri, site='plotID', species='species', count='count', 
    basal='basal', factor='forest')
summary(IV)
##        Length Class  Mode     
## values   3    -none- character
## LOT    252    -none- numeric  
## MCF    203    -none- numeric  
## YSF    224    -none- numeric
IV.LOT <- data.frame(Forest=rep("LOT", nrow(IV$LOT)),
                     species=rownames(IV$LOT),
                     importance.value=IV$LOT[, "importance.value"])
IV.MCF <- data.frame(Forest=rep("MCF", nrow(IV$MCF)),
                     species=rownames(IV$MCF),
                     importance.value=IV$MCF[, "importance.value"])
IV.YSF <- data.frame(Forest=rep("YSF", nrow(IV$YSF)),
                     species=rownames(IV$YSF),
                     importance.value=IV$YSF[, "importance.value"])
row.names(IV.LOT) <- row.names(IV.MCF) <- row.names(IV.YSF) <- NULL
IV2 <- rbind(IV.LOT, IV.MCF, IV.YSF)
summary(IV2)
##     Forest            species          importance.value 
##  Length:97          Length:97          Min.   : 0.8927  
##  Class :character   Class :character   1st Qu.: 1.5320  
##  Mode  :character   Mode  :character   Median : 3.8184  
##                                        Mean   : 9.2783  
##                                        3rd Qu.:12.0124  
##                                        Max.   :58.8949
head(IV2)
##   Forest  species importance.value
## 1    LOT Acernegu         45.08809
## 2    LOT Acersacc         28.13683
## 3    LOT Ulmurubr         23.29686
## 4    LOT Querrubr         16.49413
## 5    LOT Fraxamer         16.13852
## 6    LOT Prunsero         16.12484

4 Creating community and environmental data sets

The importance values can be used as abundance values in community ecological analyses

IV.comm <- xtabs(importance.value ~ Forest + species, data=IV2)
IV.comm <- as.data.frame.matrix(IV.comm)
IV.comm
##     Acernegu Acerrubr Acersacc  Acersp.  Aescglab Carycord Caryglab Carylaci
## LOT 45.08809 15.31176 28.13683 0.000000 16.049762 3.868702 1.060137 0.000000
## MCF  0.00000  0.00000 52.96622 2.643012  1.282767 0.000000 0.000000 0.000000
## YSF  0.00000 14.56874 46.75001 0.000000  1.086830 1.284000 3.818369 1.532039
##      Caryovat  Carysp. Carytome Castpumi Celtocci Cerccana Cornflor Diosvirg
## LOT  5.713080 0.000000 3.244267 0.000000 2.788618 2.692711 2.982106 0.000000
## MCF 19.504672 6.382445 0.000000 0.000000 1.721652 5.055798 9.090300 1.812186
## YSF  9.958558 1.530696 0.000000 1.146673 0.000000 0.000000 3.674706 0.000000
##      Fagugran Fraxamer Fraxpenn  Fraxsp. Gledtria  Juglnigr Junivirg  Liqustyr
## LOT  0.000000 16.13852 2.421933 0.000000 1.058403 0.9984521  0.00000 0.9620102
## MCF  3.383735 12.76360 0.000000 1.329682 1.743359 7.2994729 37.22705 0.0000000
## YSF 17.148552 10.53762 2.247570 0.000000 0.000000 8.1094262  0.00000 0.0000000
##     Lirituli Nysssylv Pinuresi Pinustro Pinutaed   Platocci Popudelt Popugran
## LOT 11.77381 1.212119 1.576493 9.758987 1.163062 15.8052687 7.626195 0.000000
## MCF 52.61363 0.000000 0.000000 0.000000 0.000000  2.2041259 0.000000 0.000000
## YSF 18.13605 1.940307 0.000000 4.454116 0.000000  0.9137325 0.000000 1.603921
##     Popuhete  Prunsero  Queralba  Quercocc  Quermich  Quermueh  Querprin
## LOT 0.000000 16.124836  1.852784 5.6097928 0.0000000 15.688927 0.0000000
## MCF 0.000000  1.042707 19.795049 0.9085888 0.0000000 12.012413 0.9026208
## YSF 1.111799  0.920611 58.894872 1.0164285 0.9772899  6.322651 9.0994579
##      Querrubr  Quersp.  Quervelu  Rhussp. Robipseu  Rubuocci  Sassalbi Tiliamer
## LOT 16.494126 0.000000  8.771996 0.000000 5.080334 0.8926819  3.570997 1.103378
## MCF  6.812041 1.686029  1.792256 1.022198 0.000000 0.0000000 19.852069 0.000000
## YSF 13.919268 0.000000 41.358784 0.000000 0.000000 0.0000000  7.541635 1.334284
##     Ulmuamer  Ulmurubr  Unkn11
## LOT 2.035079 23.296861 2.04689
## MCF 6.908135  8.242187 0.00000
## YSF 4.072938  2.988067 0.00000

5 Principal components analysis after Hellinger transformation

The rest of the ordination pipeline was modified from a previous Rpub…

IV.Hellinger <- disttransform(IV.comm, method='hellinger')
Ordination.model1 <- rda(IV.Hellinger, data=IV.Hellinger, scaling="species")

5.1 Plotting

plot1 <- ordiplot(Ordination.model1, scaling=1)

sites.long1 <- sites.long(plot1)
species.long1 <- species.long(plot1)
axis.long1 <- axis.long(Ordination.model1, choices=c(1, 2))

Select a subset of species

species.long1$radius <- sqrt(species.long1$axis1^2 + species.long1$axis2^2)
species.threshold <- quantile(species.long1$radius, probs=0.80)
species.long2 <- species.long1[species.long1$radius >= species.threshold, ]
species.long2
##                axis1       axis2   labels    radius
## Acernegu -0.43829682 -0.08917326 Acernegu 0.4472762
## Acerrubr -0.16530517  0.24824126 Acerrubr 0.2982441
## Fagugran  0.17440768  0.20545321 Fagugran 0.2694978
## Junivirg  0.25421426 -0.39885932 Junivirg 0.4729838
## Lirituli  0.17878529 -0.18479353 Lirituli 0.2571242
## Pinustro -0.15408506  0.12450679 Pinustro 0.1981014
## Prunsero -0.19691344 -0.04461526 Prunsero 0.2019045
## Queralba  0.27770545  0.29467244 Queralba 0.4049101
## Querprin  0.11080055  0.17514873 Querprin 0.2072531
## Quervelu  0.01428372  0.37896785 Quervelu 0.3792369

Modify the theme

BioR.theme <- theme(
        panel.background = element_blank(),
        panel.border = element_blank(),
        panel.grid = element_blank(),
        axis.line = element_line("gray25"),
        text = element_text(size = 12),
        axis.text = element_text(size = 10, colour = "gray25"),
        axis.title = element_text(size = 14, colour = "gray25"),
        legend.title = element_text(size = 14),
        legend.text = element_text(size = 14),
        legend.key = element_blank())

5.2 Final plot

plotgg1 <- ggplot() + 
    geom_vline(xintercept = c(0), color = "grey70", linetype = 2) +
    geom_hline(yintercept = c(0), color = "grey70", linetype = 2) +  
    xlab(axis.long1[1, "label"]) +
    ylab(axis.long1[2, "label"]) +  
    scale_x_continuous(sec.axis = dup_axis(labels=NULL, name=NULL)) +
    scale_y_continuous(sec.axis = dup_axis(labels=NULL, name=NULL)) +
    geom_point(data=sites.long1, 
               aes(x=axis1, y=axis2), 
               size=2, colour="blue") +
    geom_text_repel(data=sites.long1, 
               aes(x=axis1, y=axis2, label=labels), 
               size=4, colour="blue") +
    geom_segment(data=species.long2, 
                 aes(x=0, y=0, xend=axis1*1.8, yend=axis2*1.8), 
                 colour="red", alpha=0.7, size=0.7, 
                 arrow=arrow(angle=7,
                             length=unit(1, "cm"),
                             type="open")) +
    geom_text(data=species.long2, 
                    aes(x=axis1*2.0, y=axis2*2.0, label=labels),
                    colour="red") +
    BioR.theme +
    ggsci::scale_colour_npg() +
    coord_fixed(ratio=1)

plotgg1

6 Rank-abundance curves

To construct different rank-abundance curves for the different forest types, the BiodiversityR::rankabuncomp requires an environmental data set that includes the forest type as a categorical variable.

IV.env <- data.frame(forest = factor(rownames(IV.comm)))
rownames(IV.env) <- rownames(IV.comm)
RA.data <- rankabuncomp(IV.comm, y=IV.env,
                        factor="forest", return.data=TRUE,
                        specnames=c(1:15),
                        legend=FALSE,
                        xlim=c(-2, 37))
## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

## Warning in qt(0.975, df = n - 1): NaNs produced

plotgg2 <- ggplot(data=RA.data, aes(x = rank, y = abundance)) + 
    scale_x_continuous(expand=c(0, 1), sec.axis = dup_axis(labels=NULL, name=NULL)) +
    scale_y_continuous(expand=c(0, 1), sec.axis = dup_axis(labels=NULL, name=NULL)) +
    geom_line(aes(colour=Grouping), size=1) +
    geom_point(aes(colour=Grouping), size=5, alpha=0.7) +
    geom_text_repel(data=subset(RA.data, labelit == TRUE), 
        aes(label=species), 
        angle=0, nudge_x=8, nudge_y=1, show.legend=FALSE) +
    BioR.theme +
    scale_color_brewer(palette = "Set1") +
    facet_wrap(~ Grouping) +
    labs(x = "rank", y = "abundance", colour = "Forest type")

plotgg2

7 Session Info

sessionInfo()
## R version 4.0.2 (2020-06-22)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 19042)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=English_United Kingdom.1252 
## [2] LC_CTYPE=English_United Kingdom.1252   
## [3] LC_MONETARY=English_United Kingdom.1252
## [4] LC_NUMERIC=C                           
## [5] LC_TIME=English_United Kingdom.1252    
## 
## attached base packages:
## [1] tcltk     stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
## [1] ggrepel_0.8.2        ggsci_2.9            ggplot2_3.3.3       
## [4] BiodiversityR_2.14-1 vegan_2.5-6          lattice_0.20-41     
## [7] permute_0.9-5       
## 
## loaded via a namespace (and not attached):
##  [1] nlme_3.1-148        RColorBrewer_1.1-2  tools_4.0.2        
##  [4] backports_1.1.7     R6_2.4.1            rpart_4.1-15       
##  [7] Hmisc_4.4-0         nortest_1.0-4       DBI_1.1.0          
## [10] mgcv_1.8-31         colorspace_1.4-1    nnet_7.3-14        
## [13] withr_2.2.0         tidyselect_1.1.0    gridExtra_2.3      
## [16] curl_4.3            compiler_4.0.2      htmlTable_2.0.0    
## [19] sandwich_2.5-1      labeling_0.3        tcltk2_1.2-11      
## [22] effects_4.1-4       scales_1.1.1        checkmate_2.0.0    
## [25] RcmdrMisc_2.7-2     stringr_1.4.0       digest_0.6.25      
## [28] foreign_0.8-80      relimp_1.0-5        minqa_1.2.4        
## [31] rmarkdown_2.3       rio_0.5.16          base64enc_0.1-3    
## [34] jpeg_0.1-8.1        pkgconfig_2.0.3     htmltools_0.5.1.1  
## [37] Rcmdr_2.7-2         lme4_1.1-23         htmlwidgets_1.5.1  
## [40] rlang_0.4.8         readxl_1.3.1        rstudioapi_0.11    
## [43] farver_2.0.3        generics_0.1.0      zoo_1.8-8          
## [46] acepack_1.4.1       dplyr_1.0.2         zip_2.0.4          
## [49] car_3.0-8           magrittr_1.5        Formula_1.2-3      
## [52] Matrix_1.2-18       Rcpp_1.0.7          munsell_0.5.0      
## [55] abind_1.4-5         lifecycle_0.2.0     stringi_1.4.6      
## [58] yaml_2.2.1          carData_3.0-4       MASS_7.3-51.6      
## [61] grid_4.0.2          parallel_4.0.2      forcats_0.5.0      
## [64] crayon_1.3.4        haven_2.3.1         splines_4.0.2      
## [67] hms_0.5.3           knitr_1.28          pillar_1.4.4       
## [70] boot_1.3-25         glue_1.4.1          evaluate_0.14      
## [73] mitools_2.4         latticeExtra_0.6-29 data.table_1.12.8  
## [76] png_0.1-7           vctrs_0.3.4         nloptr_1.2.2.1     
## [79] cellranger_1.1.0    gtable_0.3.0        purrr_0.3.4        
## [82] xfun_0.15           openxlsx_4.1.5      survey_4.0         
## [85] e1071_1.7-3         class_7.3-17        survival_3.1-12    
## [88] tibble_3.0.1        cluster_2.1.0       statmod_1.4.34     
## [91] ellipsis_0.3.1