| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | #' Perform a cluster analysis. | 
					
						
							|  |  |  | #' | 
					
						
							|  |  |  | #' This function will cluster the data using [stats::hclust()] and | 
					
						
							|  |  |  | #' [stats::cutree()]. Every cluster with at least two members qualifies for | 
					
						
							|  |  |  | #' further analysis. Clusters are then ranked based on their size in relation | 
					
						
							|  |  |  | #' to the total number of values. The return value is a final score between | 
					
						
							|  |  |  | #' 0.0 and 1.0. Lower ranking clusters contribute less to this score. | 
					
						
							|  |  |  | #' | 
					
						
							|  |  |  | #' @param data The values that should be scored. | 
					
						
							|  |  |  | #' @param span The maximum span of values considered to be in one cluster. | 
					
						
							|  |  |  | #' @param weight The weight that will be given to the next largest cluster in | 
					
						
							|  |  |  | #'   relation to the previous one. For example, if `weight` is 0.7 (the | 
					
						
							|  |  |  | #'   default), the first cluster will weigh 1.0, the second 0.7, the third 0.49 | 
					
						
							|  |  |  | #'   etc. | 
					
						
							| 
									
										
										
										
											2022-06-16 19:45:59 +02:00
										 |  |  | #' | 
					
						
							|  |  |  | #' @return A score between 0.0 and 1.0 summarizing how much the data clusters. | 
					
						
							|  |  |  | #' | 
					
						
							|  |  |  | #' @export | 
					
						
							| 
									
										
										
										
											2022-06-28 13:31:36 +02:00
										 |  |  | clusteriness <- function(data, span = 100000, weight = 0.7) { | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   n <- length(data) | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   # Return a score of 0.0 if there is just one or no value at all. | 
					
						
							|  |  |  |   if (n < 2) { | 
					
						
							|  |  |  |     return(0.0) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   # Cluster the data and compute the cluster sizes. | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   tree <- stats::hclust(stats::dist(data)) | 
					
						
							|  |  |  |   clusters <- stats::cutree(tree, h = span) | 
					
						
							|  |  |  |   cluster_sizes <- sort(tabulate(clusters), decreasing = TRUE) | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   # Compute the "clusteriness" score. | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   score <- 0.0 | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   for (i in seq_along(cluster_sizes)) { | 
					
						
							|  |  |  |     cluster_size <- cluster_sizes[i] | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |     if (cluster_size >= 2) { | 
					
						
							| 
									
										
										
										
											2022-06-28 13:31:36 +02:00
										 |  |  |       cluster_score <- cluster_size / n | 
					
						
							|  |  |  |       score <- score + weight^(i - 1) * cluster_score # nolint | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |   score | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #' Process genes clustering their distance to telomeres. | 
					
						
							|  |  |  | #' | 
					
						
							|  |  |  | #' The result will be cached and can be reused for different presets, because | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  | #' it is independent of the reference genes in use. Most parameters are exposed | 
					
						
							|  |  |  | #' for the [clusteriness()] function. See its documentation for more | 
					
						
							|  |  |  | #' information. | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | #' | 
					
						
							| 
									
										
										
										
											2022-06-22 11:20:39 +02:00
										 |  |  | #' @param id Unique ID for the method and its results. | 
					
						
							|  |  |  | #' @param name Human readable name for the method. | 
					
						
							|  |  |  | #' @param description Method description. | 
					
						
							|  |  |  | #' | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | #' @return An object of class `geposan_method`. | 
					
						
							|  |  |  | #' | 
					
						
							|  |  |  | #' @seealso [clusteriness()] | 
					
						
							|  |  |  | #' | 
					
						
							|  |  |  | #' @export | 
					
						
							| 
									
										
										
										
											2022-06-22 11:20:39 +02:00
										 |  |  | clustering <- function(id = "clustering", | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |                        name = "Clustering", | 
					
						
							|  |  |  |                        description = "Clustering of genes", | 
					
						
							|  |  |  |                        span = 100000, | 
					
						
							| 
									
										
										
										
											2022-06-28 13:31:36 +02:00
										 |  |  |                        weight = 0.7) { | 
					
						
							| 
									
										
										
										
											2022-06-22 11:20:39 +02:00
										 |  |  |   method( | 
					
						
							|  |  |  |     id = id, | 
					
						
							|  |  |  |     name = name, | 
					
						
							|  |  |  |     description = description, | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |     function(preset, progress) { | 
					
						
							|  |  |  |       species_ids <- preset$species_ids | 
					
						
							|  |  |  |       gene_ids <- preset$gene_ids | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |       cached( | 
					
						
							|  |  |  |         "clustering", | 
					
						
							| 
									
										
										
										
											2022-06-28 13:31:36 +02:00
										 |  |  |         c(species_ids, gene_ids, span, weight), | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |         { # nolint | 
					
						
							|  |  |  |           scores <- data.table(gene = gene_ids) | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |           # Prefilter the input data by species. | 
					
						
							|  |  |  |           distances <- geposan::distances[species %chin% species_ids] | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |           genes_done <- 0 | 
					
						
							|  |  |  |           genes_total <- length(gene_ids) | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |           # Perform the cluster analysis for one gene. | 
					
						
							|  |  |  |           compute <- function(gene_id) { | 
					
						
							|  |  |  |             data <- distances[gene == gene_id, distance] | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 13:31:36 +02:00
										 |  |  |             score <- clusteriness(data, span = span, weight = weight) | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |             genes_done <<- genes_done + 1 | 
					
						
							|  |  |  |             progress(genes_done / genes_total) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             score | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |           scores[, score := compute(gene), by = gene] | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-22 11:24:30 +02:00
										 |  |  |           result( | 
					
						
							|  |  |  |             method = "clustering", | 
					
						
							|  |  |  |             scores = scores | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       ) | 
					
						
							| 
									
										
										
										
											2022-05-26 12:42:19 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   ) | 
					
						
							| 
									
										
										
										
											2021-12-16 13:01:44 +01:00
										 |  |  | } |