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):
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