{"id":16520838,"url":"https://github.com/jhrcook/jhcutils","last_synced_at":"2026-05-23T16:44:13.679Z","repository":{"id":115870255,"uuid":"177128240","full_name":"jhrcook/jhcutils","owner":"jhrcook","description":"A bunch of functions that I find myself rewriting in a many scripts.","archived":false,"fork":false,"pushed_at":"2020-08-29T13:20:46.000Z","size":4290,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-13T11:50:09.446Z","etag":null,"topics":["pkgdown","r","r-package","r-pkg","tidygraph","utilities","utilities-r","wrapper"],"latest_commit_sha":null,"homepage":"https://jhrcook.github.io/jhcutils/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jhrcook.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"publiccode":null,"codemeta":null}},"created_at":"2019-03-22T11:28:46.000Z","updated_at":"2023-01-24T17:13:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"5d94c1c4-60ce-465a-83f4-cd00c8ee441a","html_url":"https://github.com/jhrcook/jhcutils","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhrcook%2Fjhcutils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhrcook%2Fjhcutils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhrcook%2Fjhcutils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhrcook%2Fjhcutils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jhrcook","download_url":"https://codeload.github.com/jhrcook/jhcutils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241592151,"owners_count":19987311,"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":["pkgdown","r","r-package","r-pkg","tidygraph","utilities","utilities-r","wrapper"],"created_at":"2024-10-11T16:53:22.704Z","updated_at":"2026-05-23T16:44:08.629Z","avatar_url":"https://github.com/jhrcook.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 setup, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n\nset.seed(0)\n```\n# jhcutils \u003ca href=\"https://jhrcook.github.io/jhcutils/index.html\"\u003e \u003cimg src=\"man/figures/logo.png\" align=\"right\" alt=\"\" width=\"120\" /\u003e \u003c/a\u003e\n\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![R build status](https://github.com/jhrcook/jhcutils/workflows/R-CMD-check/badge.svg)](https://github.com/jhrcook/jhcutils/actions)\n[![Travis build status](https://travis-ci.org/jhrcook/jhcutils.svg?branch=master)](https://travis-ci.org/jhrcook/jhcutils)\n[![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/jhrcook/jhcutils?branch=master\u0026svg=true)](https://ci.appveyor.com/project/jhrcook/jhcutils)\n[![Coverage status](https://codecov.io/gh/jhrcook/jhcutils/branch/master/graph/badge.svg)](https://codecov.io/github/jhrcook/jhcutils?branch=master)  \n[![jhc github](https://img.shields.io/badge/GitHub-jhrcook-lightgrey.svg?style=flat\u0026logo=github)](https://github.com/jhrcook)\n[![jhc twitter](https://img.shields.io/badge/Twitter-@JoshDoesA-00aced.svg?style=flat\u0026logo=twitter)](https://twitter.com/JoshDoesa)\n[![jhc website](https://img.shields.io/badge/Website-Joshua_Cook-5087B2.svg?style=flat\u0026logo=telegram)](https://joshuacook.netlify.com)\n\n\nThese are a bunch of functions that I find myself declaring and rewriting in a many scripts and analyses.\n\nFull documentation at the ['pkgdown site'](https://jhrcook.github.io/jhcutils/index.html).\n\n## Installation\n\nYou can install 'jhcutils' with:\n\n```{r install, eval = FALSE}\ndevtools::install_github(\"jhrcook/jhcutils\")\n```\n\n```{r load_libraries, warning = FALSE, message = FALSE}\nlibrary(jhcutils)\nlibrary(datasets)\nlibrary(tidygraph)\nlibrary(dplyr)\nset.seed(0)\n```\n\n\n### Additions\n\nIf you have any recommended additions, please open an [issue](https://github.com/jhrcook/jhcutils/issues).\n\n---\n\n## General Utilities\n\n`n_unique` - return the number of unique values in a vector.\n\n`unique_na` - return the unique values in a vector, omitting `NA`.\n\n```{r uniquena}\na \u003c- c(1, 2, 3, NA, 3)\nunique_na(a)\nb \u003c- list(c(1, 2, 3, NA), c(1, 2, NA, 5))\nunique_na(b)\nunique_na(b, to_unlist = TRUE)\n```\n\n`minmax` - set limits on a vector of numeric values.\n\n```{r minmax}\nc \u003c- sample(-100:100, 20)\nc\nminmax(c, -10, 10)\n```\n\n`u_pull` - works just like `dplyr::pull()` except only returns unique values. There are also options to return the values sorted and without `NA` using the paramters `sorted` and `na.rm`, respectively.\n\n```{r upull}\nstr(mtcars$gear)\nmtcars %\u003e% u_pull(gear)\n```\n\n`vsample` - a safe wrapper for `base::sample()` that always assumes you are passing a vector.\n\n```{r vsample}\n# samples from 1:10\nsample(10)\n# just returns 10\nvsample(10)\n\n# samples from 1:5 with replacement\nsample(5, 10, replace = TRUE)\n# samples from `c(5)` with replacement \nvsample(5, 10, replace = TRUE)\n```\n\n`str_replace_us` and `str_replace_sp` - replace underscores with spaces, or *vice vera*.\n\n\n## Tidygraph\n\n```{r myplot, include=FALSE}\nlibrary(ggraph)\nmy_plot_fxn \u003c- function(gr) {\n    g \u003c- ggraph(gr, layout = \"nicely\") +\n        geom_edge_link(color = \"grey30\", width = 0.5) +\n        geom_node_point(color = \"dodgerblue\", size = 7) +\n        geom_node_text(aes(label = name), size = 4, color = \"black\") +\n        theme_void()\n    return(g)\n}\n```\n\n`quick_forestfire` and `quick_barabasi`- wrapper around `tidygraph::play_forestfire` and `tidygraph::play_barabasi_albert` except that it will return a tidygraph object with the node attribute `\"name\"`.\n\n```{r forestfire}\nforest_gr \u003c- quick_forestfire(10)\nforest_gr\nmy_plot_fxn(forest_gr) +\n    labs(title = \"Example of a quick Forest Fire graph model\")\n\nbarabasi_gr \u003c- quick_barabasi(10)\nbarabasi_gr\nmy_plot_fxn(barabasi_gr) +\n    labs(title = \"Example of a quick Barabasi-Albert graph\")\n```\n\n`quick_graph` - randomly selects one of the above random graphs.\n\n`recursive_graph_join` - recursively join a list of tidygraph objects.\n\n```{r recursivegraphjoin}\ngr_list \u003c- purrr::map(c(5, 10, 15), quick_forestfire)\ngr \u003c- recursive_graph_join(gr_list)\ngr\nmy_plot_fxn(gr) +\n    labs(title = \"Example of joining 3 forest fire graphs\")\n```\n\n`filter_component_size` - filter the components of a tidygraph object by their individual number of nodes (order).\n\n```{r filtercompsize}\ngr \u003c- tidygraph::bind_graphs(quick_forestfire(4, name = LETTERS),\n                             quick_forestfire(6, name = letters))\nigraph::count_components(gr)\nigraph::count_components(filter_component_size(gr, min_size = 5))\nigraph::count_components(filter_component_size(gr, max_size = 5))\n```\n\n`get/rm_giant_component` - either return only or everything except the giant component of a graph (i.e. the component with the most number of nodes).\n\n```{r}\ngr_large \u003c- quick_forestfire(10, name = LETTERS)\ngr_small \u003c- quick_forestfire(5, name = letters)\ngr \u003c- tidygraph::bind_graphs(gr_large, gr_small)\ngr\nget_giant_component(gr)\nrm_giant_component(gr)\n```\n\n`num_qual_neighbors` - to be used with `tidygraph::map_local_int()` to count the number of neighbors that satisfy a logical expression that is applied to the node attributes of the neighborhood. \n\n```{r num_qual_neighbors}\ngr \u003c- quick_barabasi(30)\ngr\nmy_plot_fxn(gr)\n\n# number of neighbors with a \"B\" in their name\nB_gr \u003c- gr %\u003e%\n   mutate(name_with_B = map_local_int(\n       .f = num_qual_neighbors,\n       lgl_filter = rlang::expr(stringr::str_detect(name, \"B\"))\n   ))\n\nB_gr %N\u003e%\n   filter(name_with_B \u003e 0) %\u003e%\n   my_plot_fxn()\n```\n\n\n`get_node_index` - returns the indices of the nodes that pass the expression evaluted in 'dplyr::filter()`.\n\n```{r}\n# simple equalities\nget_node_index(quick_barabasi(10), name == \"B\")\nget_node_index(quick_barabasi(10), name %in% c(\"B\", \"C\", \"D\"))\n# can also evaluate functions\nget_node_index(quick_barabasi(10), stringr::str_detect(name, \"A|B|C\"))\n```\n\n\n## Pacakge Utilities\n\n`document_df` - prints the framework for documenting a data frame object.\n\n```{r documentdf}\ndat \u003c- tibble::tibble(x = c(LETTERS[1:5]),\n                      y = c(1:5),\n                      z = list(rep(list(1:3), 5)))\ndat\ndocument_df(dat)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhrcook%2Fjhcutils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhrcook%2Fjhcutils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhrcook%2Fjhcutils/lists"}