Skip to contents

From a matrix of spectra similarity (e.g., with the cosine metric, or Pearson product moment), infer the species clusters based on a threshold above (or equal to) which spectra are considered alike.

Usage

similarity_to_clusters(sim_matrix, threshold)

Arguments

sim_matrix

A n × n similarity matrix, with n the number of spectra. Columns should be named as the rows.

threshold

A numeric value indicating the minimal similarity between two spectra. Adjust accordingly to the similarity metric used.

Value

A tibble of n rows for each spectra and 3 columns:

  • name: the rownames of the similarity matrix indicating the spectra names

  • membership: integers stating the cluster number to which the spectra belong to. It starts from 1 to c, the total number of clusters.

  • cluster_size: integers indicating the total number of spectra in the corresponding cluster.

Details

The matrix is essentially a network where nodes are spectra and links exist between spectra only if the similarity between the spectra is above the threshold.

The original idea to find the cluster members comes from a StackOverflow answer by the user ekstroem. However, here the implementation differs in two way:

  1. It relies on the connected components of the network instead of the fast greedy modularity algorithm.

  2. It uses base R functions to reduce the dependencies

See also

For similarity metrics: coop::cosine, stats::cor, Hmisc::rcorr. For using taxonomic identifications for clusters : identification_to_clusters. For further analyses: set_reference_spectra.

Examples

# Toy similarity matrix between the six example spectra of
#  three species. The cosine metric is used and a value of
#  zero indicates dissimilar spectra and a value of one
#  indicates identical spectra.
cosine_similarity <- matrix(
  c(
    1, 0.79, 0.77, 0.99, 0.98, 0.98,
    0.79, 1, 0.98, 0.79, 0.8, 0.8,
    0.77, 0.98, 1, 0.77, 0.77, 0.77,
    0.99, 0.79, 0.77, 1, 1, 0.99,
    0.98, 0.8, 0.77, 1, 1, 1,
    0.98, 0.8, 0.77, 0.99, 1, 1
  ),
  nrow = 6,
  dimnames = list(
    c(
      "species1_G2", "species2_E11", "species2_E12",
      "species3_F7", "species3_F8", "species3_F9"
    ),
    c(
      "species1_G2", "species2_E11", "species2_E12",
      "species3_F7", "species3_F8", "species3_F9"
    )
  )
)
# Delineate clusters based on a 0.92 threshold applied
#  to the similarity matrix
similarity_to_clusters(cosine_similarity, threshold = 0.92)
#> # A tibble: 6 × 3
#>   name         membership cluster_size
#>   <chr>             <int>        <int>
#> 1 species1_G2           1            4
#> 2 species2_E11          2            2
#> 3 species2_E12          2            2
#> 4 species3_F7           1            4
#> 5 species3_F8           1            4
#> 6 species3_F9           1            4