{"id":20693443,"url":"https://github.com/nanxstats/oneclust","last_synced_at":"2025-04-22T17:42:49.470Z","repository":{"id":119855194,"uuid":"288098208","full_name":"nanxstats/oneclust","owner":"nanxstats","description":"🥇 Maximum homogeneity clustering for one-dimensional data","archived":false,"fork":false,"pushed_at":"2024-04-26T01:03:40.000Z","size":7140,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-18T20:31:54.651Z","etag":null,"topics":["clustering-algorithm","feature-engineering","homogeneity","peak-calling","univariate-data"],"latest_commit_sha":null,"homepage":"https://nanx.me/oneclust/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nanxstats.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-08-17T06:12:27.000Z","updated_at":"2021-12-18T23:33:40.000Z","dependencies_parsed_at":"2024-04-26T02:24:49.467Z","dependency_job_id":"a3d53eff-e3fc-489c-86cc-380c0ac58f69","html_url":"https://github.com/nanxstats/oneclust","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanxstats%2Foneclust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanxstats%2Foneclust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanxstats%2Foneclust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nanxstats%2Foneclust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nanxstats","download_url":"https://codeload.github.com/nanxstats/oneclust/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250289321,"owners_count":21405947,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clustering-algorithm","feature-engineering","homogeneity","peak-calling","univariate-data"],"created_at":"2024-11-16T23:26:43.497Z","updated_at":"2025-04-22T17:42:49.448Z","avatar_url":"https://github.com/nanxstats.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::knit_hooks$set(pngquant = knitr::hook_pngquant)\n\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\",\n  echo = FALSE,\n  message = FALSE,\n  dev = \"ragg_png\",\n  pngquant = \"--speed=1 --quality=50\"\n)\n```\n\n# oneclust \u003cimg src=\"man/figures/logo.png\" align=\"right\" width=\"120\" /\u003e\n\n\u003c!-- badges: start --\u003e\n[![R-CMD-check](https://github.com/nanxstats/oneclust/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/nanxstats/oneclust/actions/workflows/R-CMD-check.yaml)\n[![CRAN Version](https://www.r-pkg.org/badges/version/oneclust)](https://cran.r-project.org/package=oneclust)\n[![Downloads from the RStudio CRAN mirror](https://cranlogs.r-pkg.org/badges/oneclust)](https://cran.r-project.org/package=oneclust)\n\u003c!-- badges: end --\u003e\n\nImplements the maximum homogeneity clustering algorithm for one-dimensional data described in W. D. Fisher (1958) \u003c[doi:10.1080/01621459.1958.10501479](https://www.tandfonline.com/doi/abs/10.1080/01621459.1958.10501479)\u003e via dynamic programming.\n\nCheck `vignette(\"oneclust\")` for its applications in feature engineering, regression modeling, and peak calling.\n\n## Installation\n\nYou can install oneclust from CRAN:\n\n```r\ninstall.packages(\"oneclust\")\n```\n\nOr try the development version from GitHub:\n\n```r\nremotes::install_github(\"nanxstats/oneclust\")\n```\n\n## Gallery\n\n```{r}\nlibrary(\"oneclust\")\n```\n\n### Feature engineering for high-cardinality categorical features\n\n```{r, high-cardinality, fig.width=10, fig.height=5, dpi=227}\ndf_levels \u003c- sim_postcode_levels(nlevels = 500, seed = 42)\ntrain \u003c- sim_postcode_samples(df_levels, n = 100000, threshold = 3000, prob = c(0.2, 0.1), seed = 43)\ntest \u003c- sim_postcode_samples(df_levels, n = 100000, threshold = 3000, prob = c(0.2, 0.1), seed = 44)\n\nk \u003c- 32\nlevel_hist \u003c- table(train$postcode)\nlevel_new \u003c- oneclust(level_hist, k)$cluster\n\nfeature_tr_levels \u003c- as.character(1:k)\n\nfeature_tr \u003c- as.character(level_new[match(train$postcode, names(level_hist))])\nfeature_tr \u003c- ordered(feature_tr, levels = feature_tr_levels)\n\nfeature_te \u003c- as.character(level_new[match(test$postcode, names(level_hist))])\nfeature_te \u003c- ordered(feature_te, levels = feature_tr_levels)\n\npar(mfrow = c(1, 2))\n\npar(las = 1)\nplot(feature_tr, train$label, lty = 0, xlab = \"Cluster\", ylab = \"Label\", main = \"Recoded Training Set\")\nabline(h = 0.2, col = cud(1))\nabline(h = 0.1, col = cud(2))\n\npar(las = 1)\nplot(feature_te, test$label, lty = 0, xlab = \"Cluster\", ylab = \"Label\", main = \"Recoded Test Set\")\nabline(h = 0.2, col = cud(1))\nabline(h = 0.1, col = cud(2))\n```\n\n### Grouping coefficients in regression models\n\n```{r, coefficients, fig.width=8, fig.height=8, dpi=227}\npar(mfrow = c(2, 2))\n\nset.seed(42)\nn \u003c- 100\ni \u003c- 1:n\ny \u003c- (i \u003e 20 \u0026 i \u003c 30) + 5 * (i \u003e 50 \u0026 i \u003c 70) + rnorm(n, sd = 0.1)\n\nout \u003c- genlasso::fusedlasso1d(y)\n\nbeta1 \u003c- coef(out, lambda = 1.5)$beta\nplot(beta1, main = \"Raw Estimates\")\nabline(h = 0)\n\nbeta2 \u003c- genlasso::softthresh(out, lambda = 1.5, gamma = 1)\ngrp \u003c- as.integer(beta2 != 0) + 1L\nplot(beta2, col = cud(grp), main = \"Soft-Thresholding\")\nabline(h = 0)\nlegend(\"topleft\", legend = c(\"Zero\", \"Non-zero\"), col = cud(unique(grp)), pch = 1)\n\ncl1 \u003c- oneclust(beta1, k = 2)$cluster\nplot(beta1, col = cud(cl1), main = \"Maximum Homogeneity Clustering (k = 2)\")\nabline(h = 0)\nlegend(\"topleft\", legend = paste(\"Cluster\", unique(cl1)), col = cud(unique(cl1)), pch = 1)\n\ncl2 \u003c- oneclust(beta1, k = 3)$cluster\nplot(beta1, col = cud(cl2), main = \"Maximum Homogeneity Clustering (k = 3)\")\nabline(h = 0)\nlegend(\"topleft\", legend = paste(\"Cluster\", unique(cl2)), col = cud(unique(cl2)), pch = 1)\n```\n\n### Sequential data peak calling and segmentation\n\n```{r, peak-calling, fig.width=7.5, fig.height=10, dpi=227}\nx \u003c- seq(0, 1, len = 1024)\npos \u003c- c(0.1, 0.13, 0.15, 0.23, 0.25, 0.40, 0.44, 0.65, 0.76, 0.78, 0.81)\nhgt \u003c- c(4, 5, 3, 4, 5, 4.2, 2.1, 4.3, 3.1, 5.1, 4.2)\nwdt \u003c- c(0.005, 0.005, 0.006, 0.01, 0.01, 0.03, 0.01, 0.01, 0.005, 0.008, 0.005)\n\npsignal \u003c- numeric(length(x))\nfor (i in seq(along = pos)) {\n  psignal \u003c- psignal + hgt[i] / (1 + abs((x - pos[i]) / wdt[i]))^4\n}\n\npar(mfrow = c(4, 1))\n\nplot(psignal, type = \"l\", main = \"Raw Signal\")\n\ncl \u003c- oneclust(psignal, k = 2)\nplot(psignal, type = \"h\", col = cud(cl$cluster), main = \"Peak Calling (k = 2)\")\nlegend(\"topright\", legend = paste(\"Cluster\", unique(cl$cluster)), col = cud(unique(cl$cluster)), lty = 1)\n\ncl \u003c- oneclust(psignal, k = 4)\nplot(psignal, type = \"h\", col = cud(cl$cluster + 2), main = \"Peak Calling (k = 4)\")\nlegend(\"topright\", legend = paste(\"Cluster\", unique(cl$cluster)), col = cud(unique(cl$cluster + 2)), lty = 1)\n\ncl \u003c- oneclust(psignal, k = 6, sort = FALSE)\nplot(psignal, type = \"h\", col = cud(cl$cluster), main = \"Segmentation - Preserving Data Order (k = 6)\")\nlegend(\"topright\", legend = paste(\"Cluster\", unique(cl$cluster)), col = cud(unique(cl$cluster)), lty = 1, cex = 0.8)\n```\n\n## License\n\noneclust is free and open source software, licensed under GPL-3.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnanxstats%2Foneclust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnanxstats%2Foneclust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnanxstats%2Foneclust/lists"}