From bd16f0b18a75742ff0888453dc7e574aafdc5d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20M=2E=20Alc=C3=A1ntara?= Date: Thu, 19 Feb 2026 18:04:39 +0100 Subject: [PATCH 1/5] Delete R/cum_values.R --- R/cum_values.R | 87 -------------------------------------------------- 1 file changed, 87 deletions(-) delete mode 100644 R/cum_values.R diff --git a/R/cum_values.R b/R/cum_values.R deleted file mode 100644 index 5a71281..0000000 --- a/R/cum_values.R +++ /dev/null @@ -1,87 +0,0 @@ -#' Title -#' -#' @param int_data -#' @param property -#' @param k -#' -#' @returns -#' @export -#' -#' @examples -#' -#' #For study sites sampled in multiple plots, we can use plot accumulation curves to assess whether our estimates of these dimensions are stable. The function cum_values does plot accumulation #curves for parameters that can be obtained with package igraph. For example, for the number of #nodes and links, and connectance we can use, respectively, the igraph functions "vcount", "ecount" and "edge_density". The function may take long time if *k* >> 100 (for speed, we will run this #example with just 20 resamplings). -# cum_values identical to cum_values_UNI -#' -cum_values <- function(int_data, property=c("vcount","ecount","edge_density"), k = 100){ - require(ggplot2) - - if (!"Plot" %in% names(int_data)) stop("ERROR: your interactions data lacks a column named Plots. This function requires data assembled in plots.") - nPlots <- length(unique(int_data$Plot)) - - if (nPlots < 10) - warning( - "WARNING: your are using the incidence approach with very few plots." - ) - - if(property=="vcount"){ - - part_RNs <- partial_RNs_UNI(int_data, k) - nSteps <- length(part_RNs) - borrar <- unlist(part_RNs, recursive = FALSE) - df <- data.frame(unlist(lapply(borrar, property))) - colnames(df) <- c("Value") - df$sampleSize <- sort(rep(c(1:nSteps),k)) - plot_cumm_value <- ggplot(df, aes(x=as.factor(sampleSize), y=Value)) + - geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + - geom_point(stat="summary", fun="mean") + - geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + - labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + - ggtitle("Number of species") - - outputs <- list("Data" = df, "Plot" = plot_cumm_value) - return(outputs) - - } - - if(property=="ecount"){ - - part_RNs <- partial_RNs_UNI(int_data, k) - nSteps <- length(part_RNs) - borrar <- unlist(part_RNs, recursive = FALSE) - df <- data.frame(unlist(lapply(borrar, property))) - colnames(df) <- c("Value") - df$sampleSize <- sort(rep(c(1:nSteps),k)) - plot_cumm_value <- ggplot(df, aes(x=as.factor(sampleSize), y=Value)) + - geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + - geom_point(stat="summary", fun="mean") + - geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + - labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + - ggtitle("Number of interactions") - - outputs <- list("Data" = df, "Plot" = plot_cumm_value) - return(outputs) - - } - - if(property=="edge_density"){ - - part_RNs <- partial_RNs_UNI(int_data, k) - nSteps <- length(part_RNs) - borrar <- unlist(part_RNs, recursive = FALSE) - df <- data.frame(unlist(lapply(borrar, property))) - colnames(df) <- c("Value") - df$sampleSize <- sort(rep(c(1:nSteps),k)) - plot_cumm_value <- ggplot(df, aes(x=as.factor(sampleSize), y=Value)) + - geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + - geom_point(stat="summary", fun="mean") + - geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + - labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + - ggtitle("Connectance") - - outputs <- list("Data" = df, "Plot" = plot_cumm_value) - return(outputs) - - } - -} - From f068f9e342c5b3acef9ef5c59f33158a1e2e8faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20M=2E=20Alc=C3=A1ntara?= Date: Thu, 19 Feb 2026 18:05:54 +0100 Subject: [PATCH 2/5] Delete tests/testthat/test-cum_values.R --- tests/testthat/test-cum_values.R | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 tests/testthat/test-cum_values.R diff --git a/tests/testthat/test-cum_values.R b/tests/testthat/test-cum_values.R deleted file mode 100644 index 55a8054..0000000 --- a/tests/testthat/test-cum_values.R +++ /dev/null @@ -1,15 +0,0 @@ -################################################# -#Tests for function: cum_values -################################################# - -test_that("cum_values works", { - Amoladeras <- comm_subset(RecruitNet, site = "Amoladeras") - cum_ecount <- cum_values(Amoladeras, property="ecount", k=10) - cum_vcount <- cum_values(Amoladeras, property="vcount", k=10) - cum_edge_density <- cum_values(Amoladeras, property="edge_density", k=10) - expect_equal(dim(cum_ecount$Data), c(200,2)) - expect_equal(length(unique(cum_ecount$Data$sampleSize)),20) - expect_equal(cum_ecount$Data$Value[200], 229) - expect_equal(cum_vcount$Data$Value[200], 26) - expect_equal(cum_edge_density$Data$Value[200], 0.3523077) -}) \ No newline at end of file From 9fa6798a807519760d815d52b87d105e6dfc254f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20M=2E=20Alc=C3=A1ntara?= Date: Thu, 19 Feb 2026 18:07:03 +0100 Subject: [PATCH 3/5] New test for accum_curve function --- tests/testthat/test-accum_curve.R | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/testthat/test-accum_curve.R diff --git a/tests/testthat/test-accum_curve.R b/tests/testthat/test-accum_curve.R new file mode 100644 index 0000000..c555897 --- /dev/null +++ b/tests/testthat/test-accum_curve.R @@ -0,0 +1,16 @@ +################################################# +#Tests for function: accum_curve +################################################# + +test_that("accum_curve works", { + Amoladeras <- Amoladeras_int + set.seed(123) + accum_ecount <- accum_curve(Amoladeras, property="ecount", k=10) + accum_vcount <- accum_curve(Amoladeras, property="vcount", k=10) + accum_edge_density <- accum_curve(Amoladeras, property="edge_density", k=10) + expect_equal(dim(accum_ecount$Data), c(200,2)) + expect_equal(length(unique(accum_ecount$Data$sampleSize)),20) + expect_equal(accum_ecount$Data$Value[200], 229) + expect_equal(accum_vcount$Data$Value[200], 26) + expect_equal(accum_edge_density$Data$Value[200], 0.352307692) +}) From 2f41dd7d758b769a85de6308d37631ecbf6e84a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20M=2E=20Alc=C3=A1ntara?= Date: Thu, 19 Feb 2026 18:07:51 +0100 Subject: [PATCH 4/5] New function accum_curve --- R/accum_curve.R | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 R/accum_curve.R diff --git a/R/accum_curve.R b/R/accum_curve.R new file mode 100644 index 0000000..1f606c3 --- /dev/null +++ b/R/accum_curve.R @@ -0,0 +1,120 @@ +#' Accumulation curve of network dimensions +#' +#' @description +#' Uses plot accumulation curves to assess whether the estimates of the number +#' of nodes, links, and link density (a.k.a. connectance) are stable (see Pulgar +#' et al. 2017 for other descriptors). The function cum_values plots +#' accumulation curves for parameters that can be obtained with package +#' **`igraph`** (Csardi & Nepusz, 2006). +#' +#' **NOTE**: This function is intended for data sets organised in multiple +#' plots of the same community or locality. +#' +#' @inheritParams check_interactions + +#' @param property +#' **property**: indicates the network property, obtained from igraph +#' functions, which accuracy is being evaluated. Only three options are +#' currently available: +#' - *vcount*: accuracy of the estimated number of nodes (using igraph function +#' "vcount"). +#' - *ecount*: accuracy of the estimated number of canopy-recruit interactions +#' (using igraph function "ecount"). +#' - *edge_density*: accuracy of the estimated network connectance (using +#' igraph function "edge_density). + +#' @param k +#' An integer number specifying the number of random repetitions of subsets of +#' *n* plots. In each of the *k* repetitions, a subset of *n* randomly chosen +#' plots is combined to build a partial network for which the indicated +#' property is estimated. High values provide more confident estimates of the +#' accuracy, but the function may take long time if *k* >> 100. +#' +#' @returns +#' The function returns a list of two objects: +#' - A plot representing the mean and 95% Confidence interval (i.e. 1.96 times +#' the standard error) of the estimate of the property selected when an +#' increasing number of randomly selected plots are considered. +#' - A data frame with the cumulative values of the property for each +#' repetition of *k* plots. Provided so you can prepare your own customized +#' 6accumulation plot. +#' +#' @export +#' +#' @examples +#' accum_links <- accum_curve(Amoladeras_int, property="ecount", k=10) +#' head(accum_links$Data) +#' accum_links$Plot + +accum_curve <- function(int_data, property=c("vcount","ecount","edge_density"), k = 100){ + + if (!"Plot" %in% names(int_data)) stop("Your interactions data lacks a column named Plots. This function requires data assembled in plots.") + nPlots <- length(unique(int_data$Plot)) + + if (nPlots < 10) + warning( + "You are using the incidence approach with very few plots." + ) + + if(property=="vcount"){ + + part_RNs <- partial_RNs_UNI(int_data, k) + nSteps <- length(part_RNs) + borrar <- unlist(part_RNs, recursive = FALSE) + df <- data.frame(unlist(lapply(borrar, igraph::vcount))) + colnames(df) <- c("Value") + df$sampleSize <- sort(rep(c(1:nSteps),k)) + plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + + ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + + ggplot2::geom_point(stat="summary", fun="mean") + + ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + + ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + + ggplot2::ggtitle("Number of species") + + outputs <- list("Data" = df, "Plot" = plot_cumm_value) + return(outputs) + + } + + if(property=="ecount"){ + + part_RNs <- partial_RNs_UNI(int_data, k) + nSteps <- length(part_RNs) + borrar <- unlist(part_RNs, recursive = FALSE) + df <- data.frame(unlist(lapply(borrar, igraph::ecount))) + colnames(df) <- c("Value") + df$sampleSize <- sort(rep(c(1:nSteps),k)) + plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + + ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + + ggplot2::geom_point(stat="summary", fun="mean") + + ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + + ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + + ggplot2::ggtitle("Number of interactions") + + outputs <- list("Data" = df, "Plot" = plot_cumm_value) + return(outputs) + + } + + if(property=="edge_density"){ + + part_RNs <- partial_RNs_UNI(int_data, k) + nSteps <- length(part_RNs) + borrar <- unlist(part_RNs, recursive = FALSE) + df <- data.frame(unlist(lapply(borrar, igraph::edge_density))) + colnames(df) <- c("Value") + df$sampleSize <- sort(rep(c(1:nSteps),k)) + plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + + ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + + ggplot2::geom_point(stat="summary", fun="mean") + + ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + + ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + + ggplot2::ggtitle("Connectance") + + outputs <- list("Data" = df, "Plot" = plot_cumm_value) + return(outputs) + + } + +} + From b87db5e65afd1f397c3b625a765ae6c2592815e1 Mon Sep 17 00:00:00 2001 From: Francisco Rodriguez-Sanchez Date: Thu, 19 Feb 2026 19:08:15 +0100 Subject: [PATCH 5/5] Refactor --- R/accum_curve.R | 85 +++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 60 deletions(-) diff --git a/R/accum_curve.R b/R/accum_curve.R index 1f606c3..1260050 100644 --- a/R/accum_curve.R +++ b/R/accum_curve.R @@ -3,7 +3,7 @@ #' @description #' Uses plot accumulation curves to assess whether the estimates of the number #' of nodes, links, and link density (a.k.a. connectance) are stable (see Pulgar -#' et al. 2017 for other descriptors). The function cum_values plots +#' et al. 2017 for other descriptors). The function accum_curve plots #' accumulation curves for parameters that can be obtained with package #' **`igraph`** (Csardi & Nepusz, 2006). #' @@ -37,7 +37,7 @@ #' increasing number of randomly selected plots are considered. #' - A data frame with the cumulative values of the property for each #' repetition of *k* plots. Provided so you can prepare your own customized -#' 6accumulation plot. +#' accumulation plot. #' #' @export #' @@ -46,75 +46,40 @@ #' head(accum_links$Data) #' accum_links$Plot -accum_curve <- function(int_data, property=c("vcount","ecount","edge_density"), k = 100){ +accum_curve <- function(int_data, property=c("vcount","ecount","edge_density"), k = 100) { + + property <- match.arg(property) if (!"Plot" %in% names(int_data)) stop("Your interactions data lacks a column named Plots. This function requires data assembled in plots.") nPlots <- length(unique(int_data$Plot)) if (nPlots < 10) - warning( - "You are using the incidence approach with very few plots." - ) - - if(property=="vcount"){ - - part_RNs <- partial_RNs_UNI(int_data, k) - nSteps <- length(part_RNs) - borrar <- unlist(part_RNs, recursive = FALSE) - df <- data.frame(unlist(lapply(borrar, igraph::vcount))) - colnames(df) <- c("Value") - df$sampleSize <- sort(rep(c(1:nSteps),k)) - plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + - ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + - ggplot2::geom_point(stat="summary", fun="mean") + - ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + - ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + - ggplot2::ggtitle("Number of species") - - outputs <- list("Data" = df, "Plot" = plot_cumm_value) - return(outputs) - - } - - if(property=="ecount"){ - - part_RNs <- partial_RNs_UNI(int_data, k) - nSteps <- length(part_RNs) - borrar <- unlist(part_RNs, recursive = FALSE) - df <- data.frame(unlist(lapply(borrar, igraph::ecount))) - colnames(df) <- c("Value") - df$sampleSize <- sort(rep(c(1:nSteps),k)) - plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + - ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + - ggplot2::geom_point(stat="summary", fun="mean") + - ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + - ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + - ggplot2::ggtitle("Number of interactions") + warning("You are using the incidence approach with very few plots.") - outputs <- list("Data" = df, "Plot" = plot_cumm_value) - return(outputs) + prop_settings <- list( + "vcount" = list(fun = igraph::vcount, title = "Number of species"), + "ecount" = list(fun = igraph::ecount, title = "Number of interactions"), + "edge_density" = list(fun = igraph::edge_density, title = "Connectance") + ) - } + setting <- prop_settings[[property]] - if(property=="edge_density"){ + part_RNs <- partial_RNs_UNI(int_data, k) + nSteps <- length(part_RNs) + partial_networks <- unlist(part_RNs, recursive = FALSE) - part_RNs <- partial_RNs_UNI(int_data, k) - nSteps <- length(part_RNs) - borrar <- unlist(part_RNs, recursive = FALSE) - df <- data.frame(unlist(lapply(borrar, igraph::edge_density))) - colnames(df) <- c("Value") - df$sampleSize <- sort(rep(c(1:nSteps),k)) - plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + - ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + - ggplot2::geom_point(stat="summary", fun="mean") + - ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + - ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + - ggplot2::ggtitle("Connectance") + df <- data.frame(Value = unlist(lapply(partial_networks, setting$fun))) + df$sampleSize <- sort(rep(c(1:nSteps),k)) - outputs <- list("Data" = df, "Plot" = plot_cumm_value) - return(outputs) + plot_cumm_value <- ggplot2::ggplot(df, ggplot2::aes(x=as.factor(sampleSize), y=Value)) + + ggplot2::geom_jitter(colour="turquoise3", alpha=0.5, height = 0, width=0.1) + + ggplot2::geom_point(stat="summary", fun="mean") + + ggplot2::geom_errorbar(stat="summary", fun.data="mean_se", fun.args = list(mult = 1.96), width=0.3) + + ggplot2::labs(x="Sample Size (Num. Plots)", y="Value (mean + 95%CI)") + + ggplot2::ggtitle(setting$title) - } + outputs <- list("Data" = df, "Plot" = plot_cumm_value) + return(outputs) }