Search code examples
rmathlatitude-longitude

Calculate Latitudinal Range of species abundance


I'm trying to calculate the latitudinal ranges for species (ASVs) along a transect but cannot get my head around how to do this. Basically I want the maximum latitude minus the minimum latitude where a species is present, i.e. abundance does not equal 0. For examples Species 1 is present for the first time at -35 deg S and present for the last time at -40 deg S, it's latitudinal range would be 5 degrees. Thanks!

My data looks like this:

> dput(test[1:30, c(1:5)])
structure(list(Station_neat = c("001_DCM", "001_SA", "003_DCM", 
"003_SA", "005_DCM", "005_SA", "007_DCM", "007_SA", "009_DCM", 
"009_SA", "011_DCM", "011_SA", "013_DCM", "013_SA", "015_DCM", 
"015_SA", "017_DCM", "017_SA", "019_DCM", "019_SA", "021_DCM", 
"021_SA", "023_DCM", "023_SA", "025_DCM", "025_SA", "027_DCM", 
"027_SA", "029_DCM", "029_SA"), Lat = c(-29.997, -29.997, -30.9975, 
-30.9975, -31.9995, -31.9995, -32.99816667, -32.99816667, -34.00016667, 
-34.00016667, -34.9995, -34.9995, -36.00083333, -36.00083333, 
-36.9985, -36.9985, -38.00016667, -38.00016667, -38.99833333, 
-38.99833333, -39.999, -39.999, -40.99783333, -40.99783333, -42.0005, 
-42.0005, -42.99633333, -42.99633333, -43.9975, -43.9975), asv_3 = c(80, 
0, 65, 0, 41, 0, 50, 0, 44, 0, 53, 0, 59, 0, 38, 0, 43, 0, 25, 
0, 29, 51, 35, 22, 133, 35, 159, 83, 965, 414), asv_4 = c(766, 
694, 286, 791, 421, 1202, 382, 431, 484, 684, 431, 529, 454, 
722, 621, 370, 472, 439, 394, 243, 414, 518, 297, 300, 574, 396, 
395, 1359, 1113, 541), asv_5 = c(1314, 2812, 729, 2874, 915, 
3720, 1226, 2046, 940, 1783, 1220, 2627, 986, 3195, 1514, 566, 
590, 1603, 325, 667, 748, 932, 616, 339, 1167, 1088, 988, 2333, 
1563, 2146)), row.names = c(NA, 30L), class = "data.frame")

Edit: ASVs (e.g. asv_4) are my species. I have about 600 of these.

Edit 2: Scatterplot with mean latitudinal range and latitude (see comment): enter image description here


Solution

  • Maximum latitude minus the minimum latitude where a species is present, i.e. abundance does not equal 0

    A base solution:

    lapply(test[grepl("asv", names(test))], \(x) diff(range(test$Lat[x > 0])))
    
    # $asv_3
    # [1] 14.0005
    # 
    # $asv_4
    # [1] 14.0005
    # 
    # $asv_5
    # [1] 14.0005
    

    Its dplyr equivalent:

    library(dplyr)
    
    test %>%
      summarise(across(starts_with("asv"), ~ diff(range(Lat[.x > 0]))))
    
    #     asv_3   asv_4   asv_5
    # 1 14.0005 14.0005 14.0005