Skip to content

Commit ce7455a

Browse files
committed
Added get_pam_areas, for finding areas when a PAM is input
1 parent cf210f5 commit ce7455a

File tree

8 files changed

+242
-11
lines changed

8 files changed

+242
-11
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export(estimate_DR)
99
export(estimate_MS)
1010
export(find_areas)
1111
export(find_land)
12+
export(find_pam_areas)
1213
export(get_island_areas)
1314
export(get_presence_absence)
1415
export(get_richness)

R/find_areas.R

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#'
2222
#' @param occs The dataframe that is returned by `ssarp::find_land()`. If using
2323
#' a custom occurrence record dataframe, ensure that it has the following
24-
#' columns: "acceptedScientificName", "genericName", "specificEpithet",
24+
#' columns: "genericName", "specificEpithet",
2525
#' "decimalLongitude", "decimalLatitude", "First", "Second", "Third",
2626
#' "datasetKey". The "datasetKey" column is important for GBIF records and
2727
#' identifies the dataset to which the occurrence record belongs. Custom
@@ -63,24 +63,32 @@ find_areas <- function(
6363
checkmate::assertDataFrame(occs)
6464
checkmate::testSubset(
6565
c(
66-
"acceptedScientificName",
6766
"genericName",
6867
"specificEpithet",
69-
"decimalLongitude",
70-
"decimalLatitude",
7168
"First",
7269
"Second",
7370
"Third",
7471
"datasetKey"
7572
),
7673
names(occs)
7774
)
78-
# Ensure columns are correct type
79-
checkmate::assertCharacter(occs$acceptedScientificName)
75+
# If a shapefile is input, ensure that longitude and latitude are in occs
76+
if(!is.null(shapefile)){
77+
checkmate::testSubset(
78+
c(
79+
"decimalLongitude",
80+
"decimalLatitude"
81+
),
82+
names(occs)
83+
)
84+
# And ensure that they're numeric
85+
checkmate::assertNumeric(occs$decimalLongitude)
86+
checkmate::assertNumeric(occs$decimalLatitude)
87+
}
88+
89+
# Ensure other columns are correct type
8090
checkmate::assertCharacter(occs$genericName)
8191
checkmate::assertCharacter(occs$specificEpithet)
82-
checkmate::assertNumeric(occs$decimalLongitude)
83-
checkmate::assertNumeric(occs$decimalLatitude)
8492
checkmate::assertCharacter(occs$First)
8593
checkmate::assertCharacter(occs$Second)
8694
checkmate::assertCharacter(occs$Third)

R/find_pam_areas.R

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#' Find areas of islands using a presence-absence matrix (PAM)
2+
#'
3+
#' Use a presence-absense matrix (PAM) to create a dataframe that can be
4+
#' used to generate a species-area relationship (SAR) or speciation-area
5+
#' relationship (SpAR) in the `ssarp` pipeline.
6+
#'
7+
#' PAMs summarize the occurrence
8+
#' of species across different geographic locations. The column names of a PAM
9+
#' are species names, with the exception of the first column, which specifies
10+
#' the name of locations. For each cell corresponding to a species/location
11+
#' pair, either a 1 (presence) or a 0 (absence) is input depending on whether
12+
#' the species can be found at that location or not.
13+
#'
14+
#' Using a PAM, this function will find the areas of the land masses relevant
15+
#' to the taxon of interest with two options: a built-in database of island
16+
#' names and areas, or a user-provided list of island names and areas.
17+
#'
18+
#' The default method is to reference a built-in dataset of island names
19+
#' and areas to find the areas of the landmasses relevant to the taxon of
20+
#' interest. The user may also decide to input their own custom dataframe
21+
#' including names of relevant land masses and their associated areas to
22+
#' bypass using `ssarp`'s built-in dataset.
23+
#'
24+
#' While the word "landmasses" was used heavily in this documentation, users
25+
#' supplying their own custom area dataframe or shapefile are encouraged to
26+
#' use this function in the `ssarp` workflow to create species- and speciation-
27+
#' area relationships for island-like systems such as lakes, fragmented habitat,
28+
#' and mountain peaks.
29+
#'
30+
#' @param pam A presence-absence matrix (PAM), saved as a dataframe.
31+
#' Please ensure that the PAM has
32+
#' species names (include both generic name and specific epithet,
33+
#' with an underscore separating them) as the column
34+
#' names, with the exception of the first column
35+
#' that designates locations, which must be named "Island".
36+
#' @param area_custom A dataframe including names of land masses and their
37+
#' associated areas. This dataframe should be provided when the user would like
38+
#' to bypass using the built-in database of island names and areas. Please
39+
#' ensure that the custom dataframe includes the land mass's area in a column
40+
#' called "AREA" and the name in a column called "Name". (Optional)
41+
#' @return A dataframe of species names, island names, and island areas
42+
#' @examples
43+
#' pam <- read.csv(system.file("extdata",
44+
#' "example_pam.csv",
45+
#' package = "ssarp"))
46+
#' areas <- find_pam_areas(pam = pam)
47+
#' @export
48+
49+
find_pam_areas <- function(pam, area_custom = NULL) {
50+
# Checkmate input verification
51+
checkmate::assertDataFrame(pam)
52+
checkmate::testSubset(
53+
c("Island"),
54+
names(pam)
55+
)
56+
57+
# Turn PAM into dataframe with three columns:
58+
# Island, genericName, specificEpithet
59+
# First, create a list to hold data
60+
dat <- list()
61+
for (i in seq_len(nrow(pam))) {
62+
# Get current island
63+
island <- pam$Island[i]
64+
65+
# Figure out which species are on the island (1s in row)
66+
# Species are column names, excluding the first (which is the island name)
67+
sp <- names(pam)[-1][pam[i, -1] == 1]
68+
69+
# Just in case the user input a PAM where there are 0 species on an island,
70+
# check that there is at least one species in sp before continuing
71+
if (length(sp) > 0) {
72+
# Split species names into genericName and specificEpithet for downstream
73+
split_sp <- strsplit(sp, "_")
74+
75+
# Turn into a dataframe
76+
sp_df <- do.call(rbind.data.frame, split_sp)
77+
# Fix colnames
78+
colnames(sp_df) <- c("genericName", "specificEpithet")
79+
80+
# Add island to dataframe (call it "Third" for ssarp::find_areas())
81+
sp_df$Third <- island
82+
83+
# Add this small dataframe to the list
84+
dat[[length(dat) + 1]] <- sp_df
85+
}
86+
}
87+
88+
# Turn dat into a dataframe
89+
occs <- do.call(rbind.data.frame, dat)
90+
91+
# Add "First" and "Second" columns so it can be used with ssarp::find_areas()
92+
occs$First <- NA
93+
occs$Second <- NA
94+
# They also need to be characters
95+
occs$First <- as.character(occs$First)
96+
occs$Second <- as.character(occs$Second)
97+
98+
return(find_areas(occs, area_custom))
99+
}

inst/extdata/example_pam.csv

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Island,Anolis_ahli,Anolis_alayoni,Anolis_aliniger,Anolis_allisoni,Anolis_allogus,Anolis_altitudinalis,Anolis_alumina,Anolis_alutaceus,Anolis_angusticeps,Anolis_argenteolus,Anolis_armouri,Anolis_bahorucoensis,Anolis_baleatus,Anolis_baracoae,Anolis_barahonae,Anolis_barbatus,Anolis_barbouri,Anolis_bartschi,Anolis_brevirostris,Anolis_carolinensis,Anolis_chamaeleonides,Anolis_chlorocyanus,Anolis_christophei,Anolis_cooki,Anolis_cristatellus,Anolis_cuvieri,Anolis_cyanopleurus,Anolis_cybotes,Anolis_distichus,Anolis_equestris,Anolis_etheridgei,Anolis_evermanni,Anolis_fowleri,Anolis_garmani,Anolis_grahami,Anolis_guazuma,Anolis_gundlachi,Anolis_hendersoni,Anolis_homolechis,Anolis_inexpectatus,Anolis_insolitus,Anolis_isolepis,Anolis_jubar,Anolis_krugi,Anolis_lineatopus,Anolis_longitibialis,Anolis_lucius,Anolis_luteogularis,Anolis_marcanoi,Anolis_mestrei,Anolis_noblei,Anolis_occultus,Anolis_oculatus,Anolis_olssoni,Anolis_opalinus,Anolis_ophiolepis,Anolis_poncensis,Anolis_porcatus,Anolis_porcus,Anolis_pulchellus,Anolis_reconditus,Anolis_ricordii,Anolis_roquet,Anolis_rubribarbus,Anolis_sagrei
2+
Hog Cay,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
3+
Anguilla,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
4+
Cuba,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
5+
Little Cayman,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
6+
Cayman Brac,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
7+
Anegada,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
8+
Dominican Republic,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
9+
Providenciales Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
10+
Guantanamo,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
11+
San Salvador,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
12+
Great Exuma Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
13+
Grand Cayman,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
14+
New Providence Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
15+
Guantanamo,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1
16+
Tortola,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
17+
Cuba,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1
18+
Grenada,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
19+
Cat Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
20+
Eleuthera Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
21+
Dominica,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0
22+
Martinique,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0
23+
Grand Bahama Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
24+
Long Island,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
25+
Puerto Rico,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0
26+
Jamaica,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1
27+
Dominican Republic,0,0,1,0,0,0,1,0,0,0,1,1,1,0,1,0,1,0,1,1,0,1,1,0,1,0,0,1,1,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1
28+
Cuba,1,1,0,1,1,1,0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,1,1

man/find_areas.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/find_pam_areas.Rd

Lines changed: 60 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-find_areas.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,4 @@ test_that("Inputting something other than a shapefile in 'shapefile' will
123123
cause an error", {
124124
expect_error(find_areas(occs = occs_spat,
125125
shapefile = 1))
126-
})
127-
126+
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Create test PAM
2+
pam <- as.data.frame(matrix(ncol = 3, nrow = 2))
3+
colnames(pam) <- c("Island", "G_Sp1", "G_Sp2")
4+
pam[1,] <- c("Cuba", 0, 1)
5+
pam[2,] <- c("Dominican Republic", 1, 0)
6+
7+
# Test PAM with incorrect column names
8+
pam_name <- pam
9+
colnames(pam_name) <- c("one", "two", "three")
10+
11+
# Matrix PAM
12+
pam_mat <- as.matrix(pam)
13+
14+
########
15+
16+
test_that("The find_pam_areas function returns a dataframe", {
17+
expect_s3_class(find_pam_areas(pam), "data.frame")
18+
})
19+
20+
test_that("The find_pam_areas function returns a dataframe with 6 columns", {
21+
expect_equal(ncol(find_pam_areas(pam)), 6)
22+
})
23+
24+
test_that("Inputting a dataframe without the correct column names will cause
25+
an error", {
26+
expect_error(find_pam_areas(pam_name))
27+
})
28+
29+
test_that("Inputting a matrix instead of a dataframe will cause an error", {
30+
expect_error(find_pam_areas(pam_mat))
31+
})
32+
33+
test_that("Correct island areas are returned", {
34+
test <- find_pam_areas(pam)
35+
expect_equal(test[1,6], 1.22e+11)
36+
})

0 commit comments

Comments
 (0)