Skip to content

Solving the problem with threshold_density option in associndex#62

Open
jmalcan wants to merge 3 commits intoEcologyR:mainfrom
jmalcan:main
Open

Solving the problem with threshold_density option in associndex#62
jmalcan wants to merge 3 commits intoEcologyR:mainfrom
jmalcan:main

Conversation

@jmalcan
Copy link
Copy Markdown
Collaborator

@jmalcan jmalcan commented Apr 8, 2026

He hecho los cambios que sugieren Ali y Miguel. Ahora la función no aplica ningún threshold a menos que se le indique explícitamente con un número o usando la distribución Weibull.

jmalcan added 3 commits April 8, 2026 12:54
Cambios en la función associndex y funciones que la llaman para que los cálculos por defecto no incluyan un threshold.
Updated functions called by "associndex" to set the default threshold to NULL
Updated so that, by default, there is not a threshold density. I have added an option threshold_density = "Weibull".
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies the handling of the threshold_density parameter across several functions, changing the default value to NULL and introducing a "Weibull" option for outlier-based filtering. The review feedback correctly identifies a logic issue where setting the threshold to the maximum observed density would inadvertently filter out that specific data point; using Inf is recommended to ensure no interactions are excluded when the threshold is disabled. Additionally, the reviewer provided constructive feedback regarding code style improvements, specifically addressing inconsistent indentation and the standardization of assignment operators and spacing for better readability.

Comment on lines 101 to 105
if(is.null(threshold_density)){
threshold_density = K$limit[[2]]
message("Based on Weibull distribution fitted to the observed values, the threshold density has been set to: ", threshold_density, ".")
# To effectively avoid the use of a threshold, we set its value to the maximum
# observed density.
threshold_density = max(y)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Hola, al establecer threshold_density = max(y), las interacciones con la densidad máxima serán filtradas debido a que la condición de filtrado es un menor estricto (<). Para desactivar el umbral de forma efectiva, como se indica en la documentación, sería mejor usar Inf. Esto asegurará que no se filtre ninguna interacción cuando threshold_density es NULL. También he aprovechado para mejorar el estilo del bloque.

  if (is.null(threshold_density)) {
    # To effectively avoid the use of a threshold, we set its value to infinity
    # so no interactions are filtered out.
    threshold_density <- Inf
  }

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pues es verdad!

Comment on lines +92 to +99
int_data_0<-comm_to_RN_UNI(int_data, cover_data)
db_inter_0 <- pre_associndex_UNISITE_UNI(int_data_0)
db_inter_0$Dcr <- db_inter_0$Fcr/db_inter_0$Ac
db_inter_0$Dro <- db_inter_0$Fro/db_inter_0$Ao
# Dro has repeated values for each recruit species. The next line removes repeated
# values.
unique_Dro <- stats::aggregate(Dro ~ Recruit, data = db_inter_0[, c("Recruit", "Dro")], mean)
y <- c(db_inter_0$Dcr,unique_Dro$Dro)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hola, la indentación en este bloque es inconsistente. Para mejorar la legibilidad, sería bueno ajustarla a 2 espacios. También he añadido espacios alrededor de los operadores (/, ~) y he homogeneizado el uso de <- para las asignaciones, siguiendo las guías de estilo comunes en R.

  int_data_0 <- comm_to_RN_UNI(int_data, cover_data)
  db_inter_0 <- pre_associndex_UNISITE_UNI(int_data_0)
  db_inter_0$Dcr <- db_inter_0$Fcr / db_inter_0$Ac
  db_inter_0$Dro <- db_inter_0$Fro / db_inter_0$Ao
  # Dro has repeated values for each recruit species. The next line removes repeated
  # values.
  unique_Dro <- stats::aggregate(Dro ~ Recruit, data = db_inter_0[, c("Recruit", "Dro")], mean)
  y <- c(db_inter_0$Dcr, unique_Dro$Dro)

Comment on lines +107 to +120
if(threshold_density == "Weibull"){

# Suggest a threshold value based on recruitment density outliers according
# to a Weibull distribution. Uses "extremevalues" package.
# Zero densities are common, so we will check only for suspiciously high densities.
y <- y[which(y>0)]
K <- extremevalues::getOutliers(y, method = "I", distribution = "weibull", rho=c(1,1)) # We
#consider that a value is an outlier if it is above the limit where less
#than 1 observation is expected.

threshold_density = K$limit[[2]]
n_excluded <- length(K$iRight)
message("Based on Weibull distribution fitted to the observed values, the threshold density has been set to: ", threshold_density, ". ", n_excluded, " cases were excluded.")
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hola, en este bloque también hay algunas inconsistencias de estilo. Para mejorar la legibilidad, sugiero ajustar la indentación, usar <- para las asignaciones y añadir espacios alrededor de los operadores. Te dejo una sugerencia con estos cambios.

  if (threshold_density == "Weibull") {
    # Suggest a threshold value based on recruitment density outliers according
    # to a Weibull distribution. Uses "extremevalues" package.
    # Zero densities are common, so we will check only for suspiciously high densities.
    y <- y[which(y > 0)]
    K <- extremevalues::getOutliers(y, method = "I", distribution = "weibull", rho = c(1, 1)) # We
    # consider that a value is an outlier if it is above the limit where less
    # than 1 observation is expected.

    threshold_density <- K$limit[[2]]
    n_excluded <- length(K$iRight)
    message("Based on Weibull distribution fitted to the observed values, the threshold density has been set to: ", threshold_density, ". ", n_excluded, " cases were excluded.")
  }

@jmalcan
Copy link
Copy Markdown
Collaborator Author

jmalcan commented Apr 8, 2026

No he aplicado la sugerencia de que solo se eliminen posibles outlayers si corresponden a canopies con muy baja cobertura porque no veo cómo definir, con los datos disponibles, cuando debe considerarse que una cobertura es, per se, demasiado baja para el cálculo de los índices de asociación. De todas formas, será muy raro que un outlayer de densidad se deba a una especie con alta cobertura, porque tendría que tener auténticos céspedes de reclutas bajo la copa de todos los ejemplares presentes en el muestreo.

@verducam
Copy link
Copy Markdown
Collaborator

verducam commented Apr 8, 2026

Julio, ¿no podríamos detectar coberturas extremadamente bajas con cualquier método de detección de outliers?

@jmalcan
Copy link
Copy Markdown
Collaborator Author

jmalcan commented Apr 8, 2026

Lo he intentado usando extremeValues en varias redes pero, o no salen outlayers o solo aparecen para coberturas altas. Esto creo que se debe a que las distribuciones suelen estar dominadas por los valores bajos (tipo log-normal).
De todas formas, el problema es que el esfuerzo de muestreo con las especies raras es inevitablemente bajo, lo que hace que las estimas de densidad de reclutamiento en las que participan (ya sea como canopy o como recluta) sean poco fiables: no tenemos evidencia suficiente para decir si son correctas o incorrectas.

@verducam
Copy link
Copy Markdown
Collaborator

Sí, la verdad las coberturas de las canopy vistas en un boxplot se apelotonan en la parte inferior, por lo que es difícil encontrar outliers en esa parte. Pero, por otra parte, tenemos la sensación de que Weibull es demasiado alegre eliminando densidades altas. ¿No habría manera de hacer que Weibull sea un poco más restrictivo?

@jmalcan
Copy link
Copy Markdown
Collaborator Author

jmalcan commented Apr 11, 2026

No lo comenté antes, pero también he resuelto el problema que comentaste de la repetición de valores de densidad en open: ahora cada valor aparece solo una vez. Esto debería echar la distribución más hacia la derecha (porque en open suele haber densidades muy bajas y muchos ceros), lo que normalmente debería aumentar el threshold y reducir el número de outlayers. Creo que aún no habéis podido probar la nueva versión de associndex porque me parece que Paco no ha aceptado todavía los cambios (a lo mejor es porque se me ha pasado revisar los tests de la función y por eso salta el mensaje de "All checks have failed"). A ver si ahora os parece menos restrictiva.
En cualquier caso, respecto a hacer Weibull menos estricto con los outlayers, el threshold lo he definido como el valor de densidad para el que la distribución Weibull esperaría menos de un caso. Se podría reducir a 0.5 casos (u otro valor menor de 1), pero lo veo difícil de justificar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants