#===============================================================================
# gscp_12_write_network_to_marxan_files.R
#===============================================================================
#' Compute marxan species penalty factor
#'
#' Choosing spf values
#'
#' Taken from pp. 38-39 of Marxan_User_Manual_2008.pdf.
#' Particularly note the second paragraph, titled "Getting Started".
#'
#' 3.2.2.4 Conservation Feature Penalty Factor
#'
#' Variable – ‘spf’ Required: Yes
#' Description: The letters ‘spf’ stands for Species Penalty Factor. This
#' variable is more correctly referred to as the Conservation Feature
#' Penalty Factor. The penalty factor is a multiplier that determines the
#' size of the penalty that will be added to the objective function if the
#' target for a conservation feature is not met in the current reserve
#' scenario (see Appendix B -1.4 for details of how this penalty is
#' calculated and applied). The higher the value, the greater the relative
#' penalty, and the more emphasis Marxan will place on ensuring that
#' feature’s target is met. The SPF thus serves as a way of distinguishing
#' the relative importance of different conservation features. Features of
#' high conservation value, for example highly threatened features or those
#' of significant social or economic importance, should have higher SPF
#' values than less important features. This signifies that you are less
#' willing to compromise their representation in the reserve system.
#' Choosing a suitable value for this variable is essential to achieving
#' good solutions in Marxan. If it is too low, the representation of
#' conservation features may fall short of the targets. If it is too high,
#' Marxan’s ability to find good solutions will be impaired (i.e. it will
#' sacrifice other system properties such as lower cost and greater
#' compactness in an effort to fully meet the conservation feature targets).
#'
#' Getting Started: It will often require some experimentation to determine
#' appropriate SPFs. This should be done in an iterative fashion. A good
#' place to start is to choose the lowest value that is of the same order
#' of magnitude as the number of conservation features, e.g. if you have 30
#' features, start with test SPFs of, say, 10 for all features. Do a number
#' of repeat of runs (perhaps 10) and see if your targets are being met in
#' the solutions. If not all targets are being met try increasing the SPF
#' by a factor of two and doing the repeat runs again. When you get to a
#' point where all targets are being met, decrease the SPFs slightly and
#' see if they are still being met.
#'
#' After test runs are sorted out, then
#' differing relative values can be applied, based on considerations such
#' as rarity, ecological significance, etc., as outlined above.
#' Even if all your targets are being met, always try lower values . By
#' trying to achieve the lowest SPF that produces satisfactory solutions,
#' Marxan has the greatest flexibility to find good solutions. In general,
#' unless you have some a priori reason to weight the inclusion of features
#' in your reserve system, you should start all features with the same SPF.
#' If however, the targets for one or two features are consistently being
#' missed even when all other features are adequately represented , it may
#' be appropriate to raise the SPF for these features. Once again, see the
#' MGPH for more detail on setting SPFs.
#'
#===============================================================================
#-------------------------------------------------------------------------------
#' @param spf_rule_to_use character string
#' @param num_spp integer
#' @param parameters list
#'
#' @return numeric
#' @export
#-------------------------------------------------------------------------------
compute_marxan_species_penalty_factor <- function (spf_rule_to_use,
num_spp,
parameters)
{
if (spf_rule_to_use == "POWER_OF_10")
{
spf_const_power_of_10 = 10 ^ (floor (log10 (num_spp)))
# Marxan manual (quoted above) says to back off slightly
# from the power of 10.
# Not sure what "slightly" means, but I'll try decreasing by 5%.
spf_const = round (0.95 * spf_const_power_of_10) # "decrease the SPFs slightly"
} else if (spf_rule_to_use == "CONSTANT")
{
spf_const = parameters$marxan_spf_const
} else
{
stop_bdpg (paste0 ("\n\nERROR: marxan_spf_rule = '", spf_rule_to_use, "'",
"\nMust be one of: POWER_OF_10 or CONSTANT.\n\n"))
}
return (spf_const)
}
#===============================================================================
# Hack to quiet CHECK command for data frame column names that CHECK flags
# as "no visible binding for global variable".
# This is the officially sanctioned hack for doing this, e.g., see
# https://github.com/STAT545-UBC/Discussion/issues/451
# https://github.com/tidyverse/magrittr/issues/29
# http://r.789695.n4.nabble.com/globalVariables-td4593980.html
if(getRversion() >= "2.15.1") utils::globalVariables(c("pu", "species"))
#===============================================================================
# Write out the data as Marxan input files.
#-------------------------------------------------------------------------------
#' Write network to marxan input file
#'
#' Write the network as a marxan input file.
#'
#-------------------------------------------------------------------------------
#' @param PU_spp_pair_indices data frame
#' @param PU_IDs integer vector
#' @param spp_IDs integer vector
#' @param PU_col_name character string
#' @param spp_col_name character string
#' @param parameters lilst
#' @param marxan_input_dir character string
#' @param marxan_output_dir character string
#' @param spf_const numeric
#' @param targets numeric vector
#' @param costs numeric vector
#'
#' @return numeric spf_const
#' @export
#-------------------------------------------------------------------------------
write_network_to_marxan_files = function (PU_spp_pair_indices, # app values if running on app
PU_IDs, #####!!!!!##### # All values, i.e., cor values?
spp_IDs, #####!!!!!##### # All values, i.e., cor values?
PU_col_name,
spp_col_name,
parameters,
marxan_input_dir,
marxan_output_dir,
spf_const,
targets = rep (1, length (spp_IDs)),
costs = rep (1, length (PU_IDs))
)
{
cat ("\n\n-------------------- Writing out the data as Marxan input files.\n")
sppAmount = 1
# Wasn't this value (num_PU_spp_pairs) already set earlier?
# Is this measuring the same thing and therefore, should not be reset here?
num_PU_spp_pairs = length (PU_spp_pair_indices [,PU_col_name])
#####!!!!!##### PU_IDs = unique (PU_spp_pair_indices [,PU_col_name])
num_PUs = length (PU_IDs)
#####!!!!!##### spp_IDs = unique (PU_spp_pair_indices [,spp_col_name])
num_spp = length (spp_IDs)
spp_PU_amount_table =
data.frame (species = PU_spp_pair_indices [,spp_col_name],
pu = PU_spp_pair_indices [,PU_col_name],
amount = rep (sppAmount, num_PU_spp_pairs))
#----------------------------------------------------------------------
# Sort the table in ascending order by species within planning unit.
# Taken from Wickham comment in:
# http://stackoverflow.com/questions/1296646/how-to-sort-a-dataframe-by-columns-in-r
#
# BTL - 2014 11 28
#
# Note that Marxan doesn't work correctly if the table is not sorted
# by planning unit ID (e.g., it can't find satisfying solutions).
# Ascelin said that the Marxan manual shows a picture of the values
# sorted incorrectly, i.e., by species.
#
# I should probably move this arrange() call into the code that
# writes the table as a Marxan input file. That would make sure
# that no one can write the table out incorrectly if they use that
# call.
#----------------------------------------------------------------------
spp_PU_amount_table = plyr::arrange (spp_PU_amount_table, pu, species)
#-------------------------------------------------------------------------------
#*** Need to modify the write_all...() function to prepend the
#*** name of the directory to put the results in (but can
#*** default to writing in "." instead?).
#*** Will do this later because it's not a big deal to do the copies
#*** below and when I make this change I will have to rebuild the
#*** marxan package and move copies to the R library and the nectar
#*** machines.
# write_all_marxan_input_files (PU_IDs, spp_IDs, spp_PU_amount_table,
# spf_const)
write_all_marxan_input_files (PU_IDs,
spp_IDs,
spp_PU_amount_table,
targets,
costs,
spf_const)
# Write pu.dat file.
pu_dat_file_to_cp = paste0 (parameters$marxan_pu_file_name, " ", marxan_input_dir)
system (paste0 ("cp ./", pu_dat_file_to_cp))
# Write spec file.
spec_file_to_cp = paste0 (parameters$marxan_spec_file_name, " ", marxan_input_dir)
system (paste0 ("cp ./", spec_file_to_cp))
# Write puvspr file.
puvspr_file_to_cp = paste0 (parameters$marxan_puvspr_file_name, " ", marxan_input_dir)
system (paste0 ("cp ./", puvspr_file_to_cp))
return (spf_const)
}
#===============================================================================
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.