yulab.utils/ 0000755 0001762 0000144 00000000000 15140042152 012517 5 ustar ligges users yulab.utils/tests/ 0000755 0001762 0000144 00000000000 15115331244 013666 5 ustar ligges users yulab.utils/tests/testthat/ 0000755 0001762 0000144 00000000000 15140042152 015521 5 ustar ligges users yulab.utils/tests/testthat/test-utils.R 0000644 0001762 0000144 00000001062 15115331244 017765 0 ustar ligges users test_that("%||% returns fallback only when NULL", {
expect_equal(NULL %||% 1, 1)
expect_equal(0 %||% 1, 0)
expect_equal("" %||% "x", "")
})
test_that("parse_ratio handles spaces and invalid inputs", {
expect_equal(parse_ratio("1/5"), 0.2)
expect_equal(parse_ratio(" 2 / 4 "), 0.5)
expect_true(is.na(parse_ratio("a/b")))
expect_true(is.na(parse_ratio("1/0")))
})
test_that("quiet suppresses output and returns value invisibly", {
f <- function() { cat("hello\n"); 1 }
res <- quiet(f())
expect_equal(res, 1)
expect_invisible(quiet(f()))
})
yulab.utils/tests/testthat/test-error-utils.R 0000644 0001762 0000144 00000001240 15116500304 021106 0 ustar ligges users test_that("check_file validates existence and permissions", {
tf <- tempfile()
writeLines("x", tf)
expect_silent(check_file(tf, operation = "read", must_exist = TRUE))
unlink(tf)
expect_error(check_file(tf, operation = "read", must_exist = TRUE))
})
test_that("check_directory can create missing dir", {
td <- tempfile()
expect_message(check_directory(td, create_if_missing = TRUE), "Created directory")
expect_true(dir.exists(td))
unlink(td, recursive = TRUE)
})
test_that("check_range validates numeric bounds", {
expect_silent(check_range(5, min = 1, max = 10))
expect_error(check_range(0, min = 1))
expect_error(check_range(11, max = 10))
})
yulab.utils/tests/testthat/test-cache.R 0000644 0001762 0000144 00000001647 15137763371 017717 0 ustar ligges users test_that("update_cache_item with ttl expires entries", {
item <- paste0("ttltest_", as.integer(runif(1) * 1e6))
update_cache_item(item, list(a = 1), ttl = 0.2)
val1 <- get_cache_element(item, "a")
expect_equal(val1, 1)
Sys.sleep(0.3)
val2 <- get_cache_element(item, "a")
expect_null(val2)
})
test_that("with_cache computes and caches results", {
item <- paste0("withcache_", as.integer(runif(1) * 1e6))
calls <- 0
f <- function() { calls <<- calls + 1; 42 }
v1 <- with_cache(item, "k", f, ttl = 1)
v2 <- with_cache(item, "k", f, ttl = 1)
expect_equal(v1, 42)
expect_equal(v2, 42)
expect_equal(calls, 1)
})
test_that("cache_save/cache_load round-trip", {
item <- paste0("savecache_", as.integer(runif(1) * 1e6))
update_cache_item(item, list(x = 123))
tf <- tempfile(fileext = ".rds")
cache_save(tf)
rm_cache()
cache_load(tf)
expect_equal(get_cache_element(item, "x"), 123)
unlink(tf)
})
yulab.utils/tests/testthat.R 0000644 0001762 0000144 00000000102 15115331235 015642 0 ustar ligges users library(testthat)
library(yulab.utils)
test_check("yulab.utils")
yulab.utils/MD5 0000644 0001762 0000144 00000007601 15140042152 013033 0 ustar ligges users 07046c9877c8b865caa52c261dabe6a0 *DESCRIPTION
3a9095bb4dc09e4123838743c3f3a9a8 *NAMESPACE
f1e49eeb86ede053877de3135ec908fb *NEWS.md
dea503b7e07e699c2bd4ba8d5d00bc1c *R/bib-ggtree.R
d3c9d9b61886ad96130da98b77a825ca *R/bib-knownledge.R
8c817a90acb8deb76024a36d5662c824 *R/biorxiv.R
abe3e19657d44f508ad3b08721db0a11 *R/cache.R
95effca842167b8d4ab1d11056e3e84e *R/combinations.R
664948f3ab8aa48e35c8dd268bcdf822 *R/concat.r
1e96bf6a7a239f70663880d5ffea3da8 *R/download.R
f41fec88331c3661c32540a19eda1da0 *R/error-utils.r
3f9762b961d4098f7e9eb9980d64cdbb *R/file.R
a96cd34294a7a855144c7cd3a3770df8 *R/install_zip.R
8dc56c2701ad2466e927bef5efbd3f51 *R/list.R
2f7f9ed479ca64940466e7607fd2aa7b *R/load-orgdb.r
8252645d719beddb50ac388ea53f218c *R/matrix-utils.R
89e184cc08a87f954498e149088b76bf *R/os.R
8229d906e01f2baa296ec3a8a65fc00a *R/parse_ratio.R
fc61bc16540bda29a9045368c58d2a86 *R/pkg-utils.R
1ac93d94e3f802de0cd293a9751cd53f *R/quiet.r
f49ce53dbd4709f3ec853cde9db83b3f *R/regexpr.R
ac1d7b818e77f68279c01ca8ed44cd1f *R/scale.R
876bd4024b7491400e97c757b8d3398d *R/scihub-dl.R
e0f7e2658ee96087159161d6126bf3be *R/str-utils.R
a33656388df140e42f096042e4d94c4f *R/sudo-install.R
4915960c0e996ed084d9c9b62195b314 *R/utilities.R
fbe4297a8e92938ee8fe8acfe8ddf011 *R/yulab-msg.R
da7bac5323d313dfbcdb38f8fbf613f0 *R/yulab-utils-package.R
81128a8e2c6dac0484310aefb614e6c3 *R/zzz.R
e102b8ef2ffb9aafef52223a22e88753 *inst/prototype/GEO.r
fe6013508f10ad5584815759267861f0 *inst/prototype/sra.r
d611cc86140e279caf3e3acb788b6153 *man/c2.Rd
cca3079b94e3205eab328338d83472a6 *man/check_directory.Rd
41e2363d0b9dbd7c989135de2d257fa2 *man/check_file.Rd
dba97e8704ab033d8ca1a19ef010541e *man/check_input.Rd
0e2b376e4244e8d281bb5bdb089c6c05 *man/check_packages.Rd
7e1a1747edf58ad6661d6b614fadba7e *man/check_range.Rd
740f5276df44ad1e6766f7a37fe1d21a *man/combinations.Rd
53e2e7991daa9f006d949f5a282c5fc8 *man/cran-bioc-pkg.Rd
30244d124db9d30e3aee0968404ad1d3 *man/download_yulab_file.Rd
880045bd07af6869c5d49e6498690bc4 *man/exec.Rd
0e03dbc2bf8b5157dbea8e8400f2f27f *man/get_dependencies.Rd
d6c94e132951aa5c506492b32ac47881 *man/get_fun_from_pkg.Rd
d73ad3a3ad0f05cd91f6f1b20a9db534 *man/github-pkg.Rd
2582f44cfd945f1061ffd043eeb8db02 *man/has_internet.Rd
c8e2293b15f6c8ee6229692984596492 *man/install_zip.Rd
706162775b754111bb910a6ca34bb49c *man/install_zip_gh.Rd
42f5ad71d13e5b9bb13a9af0f591e868 *man/is.installed.Rd
df477ec6d0b0b783d7456b75fb647e60 *man/load_OrgDb.Rd
e0e8a92b36a60d28d4443bd183196071 *man/ls2df.Rd
6ad39ca2459889f1cdd3f10b50cca2b1 *man/mat2df.Rd
035dbcab8d8db17527a76278426722ca *man/mat2list.Rd
8f7d212a3555294fdf51d4fd17a49751 *man/mypkg.Rd
f04b08482d12259ff32747b9cd2ad12b *man/o.Rd
fe2d50b228cda6d6e3d273303a7aa8b8 *man/packageTitle.Rd
0deb9a929023b7af75f82f054e58ab52 *man/parse_ratio.Rd
8b5b64fc35189d6bc02370aab93b25c1 *man/pload.Rd
42b3f1127c63dc0d079355e5d890eaeb *man/quiet.Rd
aa47acf576dd6ca373c05f848849fc5e *man/rbindlist.Rd
715e6475373b8eb14fac52156029c74f *man/read.cb.Rd
cc2839493bf6acf44d44883bfb9edea3 *man/regexpr-style.Rd
e4439fe352c1817015d3bc28bd4f5abf *man/scale_range.Rd
7ca4626445edad5c55b084c9a360cff2 *man/scihub-dl.Rd
a6e88efcf58d3da72fa22a3c1599ab54 *man/show_in_excel.Rd
53970495fb075dbf109342425fc476f0 *man/str-detect.Rd
a0cf2e8b4cd05f4f3e123e90d30d9b5d *man/str-extract.Rd
d07a2ecf308318f9102443d48b28552a *man/str-starts-ends.Rd
7dba62bb489bd86d35cea158dda28fb8 *man/str_wrap.Rd
368a8cb1079edd073caf5c30b99c6aaf *man/user_dir.Rd
c39f100ffb3e5a4a2ad75cb20c2f64ad *man/yread.Rd
f849c9b93ab305daea0fbb2084a830df *man/yulab-cache.Rd
29845f48b7194470367c623b704b9cf9 *man/yulab-message.Rd
eedc7b6680597a4df3d869fe84f9ca5c *man/yulab.utils-package.Rd
d4fd3e73765c9b7f9e2de1137d9a6dd1 *man/yulab_msg.Rd
a4cc960ea1ca60075970eb7923df396c *tests/testthat.R
9acf2bc9f231a93b151790bde74911e8 *tests/testthat/test-cache.R
6b9af5d566b8bf3d16330d4f4b4d7f5f *tests/testthat/test-error-utils.R
772618f20ab0addf9310247e5a7dea35 *tests/testthat/test-utils.R
yulab.utils/R/ 0000755 0001762 0000144 00000000000 15114322400 012716 5 ustar ligges users yulab.utils/R/cache.R 0000644 0001762 0000144 00000012772 15117723302 014126 0 ustar ligges users # caching mechanism
# - get_cache_item() auto-initializes cache items if they don't exist
# - get_cache_element() retrieves specific elements from cache items
# - update_cache_item() stores data in cache items
# - rm_cache_item() removes cache items
.yulabCache <- new.env(parent = emptyenv())
#' @rdname yulab-cache
#' @export
#' @family cache-utils
initial_cache <- function() {
rm(list = ls(envir = .yulabCache), envir = .yulabCache)
}
#' @rdname yulab-cache
#' @export
#' @family cache-utils
get_cache <- function() {
.yulabCache
}
#' @rdname yulab-cache
#' @export
#' @family cache-utils
rm_cache <- function() {
rm(list = ls(envir = .yulabCache), envir = .yulabCache)
}
#' @rdname yulab-cache
#' @export
#' @family cache-utils
initial_cache_item <- function(item) {
env <- get_cache()
assign(item, list(), envir = env)
}
#' @rdname yulab-cache
#' @export
get_cache_item <- function(item) {
env <- get_cache()
if (!exists(item, envir = env)) {
initial_cache_item(item)
}
get(item, envir = env, inherits = FALSE)
}
#' @rdname yulab-cache
#' @export
rm_cache_item <- function(item) {
env <- get_cache()
if (exists(item, envir = env)) {
rm(list = item, envir = env)
}
}
#' Cache intermediate data
#'
#' Utilities to cache intermediate data: initialize items, update items,
#' remove items, and retrieve elements.
#'
#' @rdname yulab-cache
#' @param item Cache item name
#' @param elements Elements to cache
#' @param default Default value if cache element is missing
#' @param prune_expired Logical, whether to prune expired items
#' @param ttl Time-to-live in seconds
#' @return Cache environment, item, or selected elements
#' @importFrom utils modifyList
#' @importFrom stats setNames
#' @export
#' @examples
#' \dontrun{
#' slow_fib <- function(x) {
#' if (x < 2) return(1)
#' slow_fib(x-2) + slow_fib(x-1)
#' }
#'
#' fast_fib <- function(x) {
#' if (x < 2) return(1)
#' res <- get_cache_element('fibonacci', as.character(x))
#' if (!is.null(res)) {
#' return(res)
#' }
#' res <- fast_fib(x-2) + fast_fib(x-1)
#' e <- list()
#' e[[as.character(x)]] <- res
#' update_cache_item('fibonacci', e)
#' return(res)
#' }
#'
#' system.time(slow_fib(30))
#' system.time(fast_fib(30))
#'
#' }
#' @family cache-utils
update_cache_item <- function(item, elements, ttl = NULL) {
msg <- "new elements should be stored as a named list"
if (!inherits(elements, 'list')) {
stop(msg)
}
if (is.null(names(elements))) {
stop(msg)
}
if(any(names(elements) == "")) {
stop(msg)
}
if (!is.null(ttl)) {
expires <- Sys.time() + as.difftime(ttl, units = "secs")
elements <- lapply(elements, function(v) list(value = v, expires = expires))
names(elements) <- names(elements)
}
env <- get_cache()
res <- get_cache_item(item)
res <- modifyList(res, elements)
assign(item, res, envir = env)
}
#' @rdname yulab-cache
#' @family cache-utils
#' @export
get_cache_element <- function(item, elements, default = NULL, prune_expired = TRUE) {
x <- get_cache_item(item)
fetch_one <- function(k) {
val <- x[[k]]
if (is.null(val)) return(default)
if (is.list(val) && !is.null(val$expires)) {
if (prune_expired && isTRUE(Sys.time() > val$expires)) {
rm_cache_entry(item, k)
return(default)
}
return(val$value)
}
val
}
n <- length(elements)
if (n == 1) return(fetch_one(elements))
setNames(lapply(elements, fetch_one), elements)
}
rm_cache_entry <- function(item, key) {
env <- get_cache()
x <- get_cache_item(item)
x[[key]] <- NULL
assign(item, x, envir = env)
}
#' @rdname yulab-cache
#' @export
prune_cache_item <- function(item) {
x <- get_cache_item(item)
expired <- vapply(names(x), function(k) {
v <- x[[k]]
is.list(v) && !is.null(v$expires) && isTRUE(Sys.time() > v$expires)
}, logical(1))
if (any(expired)) {
x[names(x)[expired]] <- NULL
env <- get_cache()
assign(item, x, envir = env)
}
invisible(TRUE)
}
#' @rdname yulab-cache
#' @export
cache_list_items <- function() {
ls(envir = get_cache())
}
#' @rdname yulab-cache
#' @export
cache_size <- function() {
env <- get_cache()
items <- ls(envir = env)
sizes <- vapply(items, function(k) utils::object.size(get(k, envir = env)), numeric(1))
sum(sizes)
}
#' @rdname yulab-cache
#' @param path File path to save or load cache
#' @export
cache_save <- function(path) {
env <- get_cache()
obj <- as.list(env)
saveRDS(obj, path)
invisible(path)
}
#' @rdname yulab-cache
#' @export
cache_load <- function(path) {
obj <- readRDS(path)
env <- get_cache()
for (k in names(obj)) assign(k, obj[[k]], envir = env)
invisible(TRUE)
}
#' @rdname yulab-cache
#' @param key Element key
#' @param compute Function to compute value when missing
#' @param ttl Time-to-live in seconds
#' @export
with_cache <- function(item, key, compute, ttl = NULL) {
k <- as.character(key)
val <- get_cache_element(item, k)
if (!is.null(val)) return(val)
res <- compute()
e <- list()
e[[k]] <- res
update_cache_item(item, e, ttl = ttl)
res
}
yulab.utils/R/pkg-utils.R 0000644 0001762 0000144 00000014142 15117723102 014771 0 ustar ligges users #' Load a package
#'
#' Uses `library()` to load `package`. If not installed, attempts installation
#' via `rlang::check_installed()` (optionally using `BiocManager::install()`).
#' @title pload
#' @param package package name
#' @param action Installation function; `"auto"` tries `BiocManager::install()` if available
#' @return the selected package loaded to the R session
#' @importFrom rlang as_name
#' @importFrom rlang enquo
#' @importFrom rlang check_installed
#' @importFrom cli cli_h2
#' @importFrom utils getFromNamespace
#' @export
#' @author Guangchuang Yu
#' @family pkg-utils
pload <- function(package, action = "auto") {
pkg <- as_name(enquo(package))
if (action == "auto") {
if (is.installed("BiocManager")) {
install <- getFromNamespace("install", "BiocManager")
action <- function(package, ask=FALSE, update=FALSE, ...) {
install(package, ask=ask, update = update, ...)
}
} else {
action <- NULL
}
}
check_installed(pkg, action = action)
pkg <- sub("\\w+/", "", pkg) # for github pkg: repo/pkg
cli::cli_h2(sprintf("loading the package: %s", pkg))
library(pkg, character.only = TRUE)
}
#' Get reverse dependencies
#'
#'
#' @title get_dependencies
#' @param pkg package name
#' @param repo 'CRAN' and/or 'BioC'
#' @return reverse dependencies
## @importFrom BiocInstaller biocinstallRepos
#' @importFrom tools package_dependencies
#' @export
#' @author Guangchuang Yu
#' @family pkg-utils
get_dependencies <- function(pkg, repo=c("CRAN", "BioC")) {
rp <- get_repo(repo)
db <- utils::available.packages(repo=rp)
tools::package_dependencies(pkg, db=db, reverse=TRUE)
}
get_repo <- function(repo = c("CRAN", "BioC")) {
rp <- c()
if ('CRAN' %in% repo) {
cran <- getOption("repos")["CRAN"]
if (is.null(cran)) {
cran <- "http://cloud.r-project.org/"
}
rp <- c(rp, cran)
}
if ('BioC' %in% repo) {
bioc <- getOption("BioC_mirror")
if (is.null(bioc)) {
bioc <- "https://mirrors.tuna.tsinghua.edu.cn/bioconductor/"
}
rp <- c(rp, bioc)
}
## options(repos = biocinstallRepos())
sub("/$", "", rp)
}
#' Extract package title
#'
#'
#' @title packageTitle
#' @param pkg package name
#' @param repo 'CRAN' and/or 'BioC'
#' @return reverse dependencies
#' @importFrom utils packageDescription
#' @export
#' @author Guangchuang Yu
#' @family pkg-utils
packageTitle <- function(pkg, repo='CRAN') {
title <- tryCatch(packageDescription(pkg)$Title, error=function(e) NULL)
if (is.null(title)) {
repo_url <- get_repo(repo)
if (repo == "CRAN") {
url <- sprintf("%s/package=%s", repo_url, pkg)
} else {
bioc_type <- c("bioc", "workflows", "data/annotation", "data/experiment")
url <- sprintf("%s/packages/release/%s/html/%s.html", repo_url, bioc_type, pkg)
}
for (u in url) {
x <- tryCatch({
if (is.installed("httr2")) {
req <- httr2::request(u) |> httr2::req_timeout(5)
resp <- httr2::req_perform(req)
httr2::resp_body_string(resp)
} else {
yread(u)
}
}, error = function(e) NULL)
if (!is.null(x)) {
break()
}
}
if (is.null(x)) {
return(NA)
}
if (length(grep("
tt <- sub(".*\\s*(.*?)\\s*.*", "\\1", paste(x, collapse = " "))
title <- tt
} else {
i <- grep('^\\s*', x)
if (grepl("
$", x[i])) {
xx <- x[i]
} else {
j <- grep('
$', x)
xx <- paste(x[i:j], collapse=" ")
}
title <- gsub('$', '', gsub('\\s*', '', xx))
}
}
sub("^\\w+\\s*:\\s*", "", gsub("\n", " ", title))
}
#' Check whether packages are installed
#' @title is.installed
#' @param packages package names
#' @return logical vector
#' @export
#' @examples
#' is.installed(c("dplyr", "ggplot2"))
#' @author Guangchuang Yu
#' @family pkg-utils
is.installed <- function(packages) {
vapply(packages, function(package) {
system.file(package=package) != ""
}, logical(1))
}
#' load function from package
#'
#'
#' @title get_fun_from_pkg
#' @param pkg package
#' @param fun function
#' @return function
#' @export
#' @examples
#' get_fun_from_pkg('utils', 'zip')
#' @author Guangchuang Yu
#' @family pkg-utils
get_fun_from_pkg <- function(pkg, fun) {
## v1
##
## requireNamespace(pkg)
## eval(parse(text=paste0(pkg, "::", fun)))
## v2
##
## require(pkg, character.only = TRUE)
## eval(parse(text = fun))
# check_pkg(pkg)
utils::getFromNamespace(fun, pkg)
}
#' Markdown link to CRAN/Bioconductor
#'
#'
#' @rdname cran-bioc-pkg
#' @param pkg package name
#' @return md text string
#' @export
#' @author Guangchuang Yu
#' @family pkg-utils
CRANpkg <- function(pkg) {
cran <- "https://CRAN.R-project.org/package"
fmt <- "[%s](%s=%s)"
sprintf(fmt, pkgfmt(pkg), cran, pkg)
}
#' @rdname cran-bioc-pkg
#' @export
Biocpkg <- function(pkg) {
sprintf("[%s](http://bioconductor.org/packages/%s)", pkgfmt(pkg), pkg)
}
#' Markdown link to GitHub
#'
#'
#' @rdname github-pkg
#' @param user github user
#' @param pkg package name
#' @return md text string
#' @export
#' @author Guangchuang Yu
#' @family pkg-utils
Githubpkg <- function(user, pkg) {
gh <- "https://github.com"
fmt <- "[%s](%s/%s/%s)"
sprintf(fmt, pkgfmt(pkg), gh, user, pkg)
}
#' Markdown link to a package
#'
#'
#' @title mypkg
#' @param pkg package name
#' @param url package url
#' @return md text string
#' @export
#' @author Guangchuang Yu
#' @family pkg-utils
mypkg <- function(pkg, url) {
fmt <- "[%s](%s)"
sprintf(fmt, pkgfmt(pkg), url)
}
pkgfmt <- function(pkg) {
fmt <- getOption('yulab.utils_pkgfmt', default="%s")
sprintf(fmt, pkg)
}
yulab.utils/R/download.R 0000644 0001762 0000144 00000005006 15117722605 014667 0 ustar ligges users mydownload <- function(url, destfile) {
if (is.installed('httr2')) {
req <- httr2::request(url) |> httr2::req_progress()
req |> httr2::req_perform(path = destfile)
} else {
download.file(url = url, destfile = destfile)
}
}
#' Process YuLab File Download
#'
#' @param destfile character. Local file path.
#' @param urls character vector. Base URLs for download. Remote is is `urls/basename(destfile)`
#' @param gzfile logical. Whether the remote file is gzipped.
#' @param appname character. R package name.
#' @author Guangchuang Yu
#' @importFrom utils read.delim
#' @export
download_yulab_file <- function(destfile, urls, gzfile = FALSE, appname = NULL) {
file0 <- basename(destfile)
if (!is.null(appname)) {
destfile <- file.path(user_dir(appname), file0)
}
need_dl <- TRUE
dl_url <- urls[1]
if (file.exists(destfile)) {
need_dl <- FALSE
for (url in urls) {
md5_url <- sprintf("%s/md5.txt", url)
md5 <- tryCatch(read.delim(md5_url, header = FALSE), error = function(e) NULL)
if (!is.null(md5)) {
md5_remote <- md5[md5[, 1] == file0, 2]
if (length(md5_remote) > 0) {
md5_local <- digest::digest(destfile, algo = 'md5', file = TRUE)
if (md5_remote != md5_local) {
message(sprintf("%s is outdated, download the latest version...", file0))
need_dl <- TRUE
dl_url <- url
}
break
}
}
}
} else {
message(sprintf("%s is not found, download it online...", file0))
}
if (need_dl) {
if (dl_url != urls[1]) {
urls <- unique(c(dl_url, urls))
}
for (url in urls) {
if (gzfile) {
furl <- sprintf('%s/%s.gz', url, file0)
tpfile <- sprintf("%s.gz", destfile)
} else {
furl <- sprintf('%s/%s', url, file0)
tpfile <- destfile
}
res <- tryCatch({
mydownload(furl, tpfile)
if (gzfile) {
check_pkg('R.utils')
R.utils::gunzip(tpfile, overwrite = TRUE)
}
TRUE
}, error = function(e) FALSE)
if (res) break
}
}
return(destfile)
}
yulab.utils/R/os.R 0000644 0001762 0000144 00000004064 15115331213 013471 0 ustar ligges users #' run system command
#' @family os-utils
#'
#'
#' @title exec
#' @param command system command to run
#' @return An `exec` instance that stores system command outputs
#' @export
#' @author Guangchuang Yu
exec <- function(command) {
res <- system(command, intern=TRUE)
structure(res, class = "exec")
}
#' @method print exec
#' @export
print.exec <- function(x, ...) {
cat(x, sep='\n')
}
which_cmd <- function(bin) {
os <- which_os()
which <- "which"
if (os == "Windows") {
which <- "where"
}
command <- sprintf("%s %s", which, bin)
return(command)
}
has_bin <- function(bin) {
command <- which_cmd(bin)
exit_code <- system(command,
ignore.stdout = TRUE,
ignore.stderr = TRUE)
return(exit_code == 0)
}
where <- function(bin) {
if (!has_bin(bin)) return("")
command <- which_cmd(bin)
exec(command)
}
#' test for internect connection via reading lines from a URL
#' @family os-utils
#'
#'
#' @title has_internet
#' @param site URL to test connection
#' @return logical value
#' @export
#' @author Guangchuang Yu
has_internet <- function(site = "https://www.baidu.com/") {
ret <- tryCatch(
suppressWarnings(readLines(site, n = 1)),
error = function(e) NULL
)
return(!is.null(ret))
}
which_os <- function() {
Sys.info()[["sysname"]]
}
#' get the user dir to save app caches, logs and data (a wrapper function of `rappdirs::user_cache_dir()`)
#' @family os-utils
#'
#' @title user_dir
#' @param appname App name
#' @param appauthor App author
#' @param ... additional parameters
#' @return a directory (created if not exists)
#' @importFrom rappdirs user_data_dir
#' @export
#' @author Guangchuang Yu
user_dir <- function(appname = NULL, appauthor = NULL, ...) {
dir <- rappdirs::user_data_dir(
appname = appname,
appauthor = appauthor,
...)
if (!dir.exists(dir)) dir.create(dir, recursive = TRUE)
return(dir)
}
yulab.utils/R/combinations.R 0000644 0001762 0000144 00000000500 14471060615 015535 0 ustar ligges users #' all possible combinations of n sets
#'
#' @title combinations
#' @param n number of sets
#' @return a list of all combinations
#' @importFrom utils combn
#' @export
combinations <- function(n){
l <- lapply(seq_len(n), function(x){
m <- combn(n,x)
mat2list(m)
})
unlist(l, recursive = F)
}
yulab.utils/R/list.R 0000644 0001762 0000144 00000001414 15116450416 014027 0 ustar ligges users #' Row-bind a list
#'
#'
#' @title rbindlist
#' @param x List with similar elements that can be row-bound
#' @return `data.frame`
#' @author Guangchuang Yu
#' @export
rbindlist <- function(x) {
do.call('rbind', x)
}
#' Convert a list of vectors to a data.frame
#'
#'
#' @title Convert a list of vectors (e.g., gene IDs) to `data.frame`
#' @param inputList List of vectors
#' @return `data.frame`
#' @export
ls2df <- function(inputList) {
# ldf <- lapply(1:length(inputList), function(i) {
ldf <- lapply(seq_len(length(inputList)), function(i) {
data.frame(category=rep(names(inputList[i]),
length(inputList[[i]])),
value=inputList[[i]])
})
do.call('rbind', ldf)
}
yulab.utils/R/bib-ggtree.R 0000644 0001762 0000144 00000023111 14764742645 015101 0 ustar ligges users bib_ggtree <- function(id) {
bib <- c(
jgg2024 = bib_shinyTempSignal_jgg2024,
bib2022 = bib_ggmsa_bib2022,
book = bib_ggtree_book2022,
imeta2022 = bib_ggtree_imeta2022,
cpb2020 = bib_ggtree_cpb2020,
mbe2020 = bib_treeio_mbe2020,
mbe2018 = bib_ggtree_mbe2018,
mee2017 = bib_ggtree_mee2017
)
if (!id %in% names(bib)) return(NULL)
bib[id]
}
ref_ggtree <- function() {
refs <- c(
shinyTempSignal = paste(
"L Zhan, X Luo, W Xie, XA Zhu, Z Xie, J Lin, L Li, W Tang, R Wang, L Deng, Y Liao, B Liu, Y Cai, Q Wang, S Xu, G Yu.",
"shinyTempSignal: an R shiny application for exploring temporal and other phylogenetic signals.",
"Journal of Genetics and Genomics 2024, 51(7):762-768. doi: 10.1016/j.jgg.2024.02.004"),
ggtreeBook = paste(
"Guangchuang Yu. ",
"Data Integration, Manipulation and Visualization of Phylogenetic Trees (1st edition).",
"Chapman and Hall/CRC. 2022, doi:10.1201/9781003279242, ISBN: 9781032233574\n"),
ggtreeCPB = paste0(
"Guangchuang Yu. ",
"Using ggtree to visualize data on tree-like structures. ",
"Current Protocols in Bioinformatics. 2020, 69:e96. doi:10.1002/cpbi.96\n"
),
ggtree_imeta = paste0(
"Shuangbin Xu, Lin Li, Xiao Luo, Meijun Chen, Wenli Tang, Li Zhan, Zehan Dai, Tommy T. Lam, Yi Guan, Guangchuang Yu. ",
"Ggtree: A serialized data object for visualization of a phylogenetic tree and annotation data. ",
"iMeta 2022, 1(4):e56. doi:10.1002/imt2.56\n"),
ggtreeMBE = paste0(
"Guangchuang Yu, Tommy Tsan-Yuk Lam, Huachen Zhu, Yi Guan. ",
"Two methods for mapping and visualizing associated data on phylogeny using ggtree. ",
"Molecular Biology and Evolution. 2018, 35(12):3041-3043. doi:10.1093/molbev/msy194\n"
),
ggtree = paste0(
"Guangchuang Yu, David Smith, Huachen Zhu, Yi Guan, Tommy Tsan-Yuk Lam. ",
"ggtree: an R package for visualization and annotation of phylogenetic trees with their covariates and other associated data. ",
"Methods in Ecology and Evolution. 2017, 8(1):28-36. doi:10.1111/2041-210X.12628\n"
),
treeio = paste0(
"LG Wang, TTY Lam, S Xu, Z Dai, L Zhou, T Feng, P Guo, CW Dunn, BR Jones, T Bradley, H Zhu, Y Guan, Y Jiang, G Yu. ",
"treeio: an R package for phylogenetic tree input and output with richly annotated and associated data. ",
"Molecular Biology and Evolution. 2020, 37(2):599-603. doi: 10.1093/molbev/msz240\n"
),
ggtreeExtra = paste0(
"S Xu, Z Dai, P Guo, X Fu, S Liu, L Zhou, W Tang, T Feng, M Chen, L Zhan, T Wu, E Hu, Y Jiang, X Bo, G Yu. ",
"ggtreeExtra: Compact visualization of richly annotated phylogenetic data. ",
"Molecular Biology and Evolution. 2021, 38(9):4039-4042. doi: 10.1093/molbev/msab166\n"
),
ggmsa = paste(
"L Zhou, T Feng, S Xu, F Gao, TT Lam, Q Wang, T Wu, H Huang, L Zhan, L Li, Y Guan, Z Dai, G Yu.",
"ggmsa: a visual exploration tool for multiple sequence alignment and associated data.",
"Bioinformatics. 2022, 23(4):bbac222. 10.1093/bib/bbac222"
)
)
return(refs)
}
refs <- ref_ggtree()
bib_ggtree_book2022 <- bibentry(
bibtype = "book",
title = "Data Integration, Manipulation and Visualization of Phylogenetic Treess",
author = person("Guangchuang", "Yu"),
publisher = "Chapman and Hall/{CRC}",
year = "2022",
edition = "1st edition",
doi = "10.1201/9781003279242",
url = "https://www.amazon.com/Integration-Manipulation-Visualization-Phylogenetic-Computational-ebook/dp/B0B5NLZR1Z/",
textVersion = refs['ggtreeBook']
)
bib_ggtree_imeta2022 <- bibentry(
bibtype = "article",
title = "Ggtree: A serialized data object for visualization of a phylogenetic tree and annotation data",
author = personList(
person("Shuangbin", "Xu"),
person("Lin", "Li"),
person("Xiao", "Luo"),
person("Meijun", "Chen"),
person("Wenli", "Tang"),
person("Li", "Zhan"),
person("Zehan", "Dai"),
person("Tommy T. Lam"),
person("Yi", "Guan"),
person("Guangchuang", "Yu")
),
year = "2022",
journal = "iMeta",
volume = "1",
number = "4",
pages = "e56",
doi = "10.1002/imt2.56",
url = "https://onlinelibrary.wiley.com/doi/full/10.1002/imt2.56",
textVersion = refs['ggtree_imeta']
)
bib_ggtree_cpb2020 <- bibentry(
bibtype = "article",
title = "Using ggtree to Visualize Data on Tree-Like Structures",
author = person("Guangchuang", "Yu"),
year = "2020",
journal = "Current Protocols in Bioinformatics",
volume = "69",
pages = "e96",
number = "1",
url = "https://currentprotocols.onlinelibrary.wiley.com/doi/abs/10.1002/cpbi.96",
doi = "10.1002/cpbi.96",
textVersion = refs['ggtreeCPB']
)
bib_ggtree_mbe2018 <- bibentry(
bibtype = "article",
title = "Two methods for mapping and visualizing associated data on phylogeny using ggtree.",
author = personList(
as.person("Guangchuang Yu"),
as.person("Tommy Tsan-Yuk Lam"),
as.person("Huachen Zhu"),
as.person("Yi Guan")
),
year = "2018",
journal = "Molecular Biology and Evolution",
volume = "35",
issue = "2",
number = "",
pages = "3041-3043",
doi = "10.1093/molbev/msy194",
PMID = "",
url = "https://academic.oup.com/mbe/article/35/12/3041/5142656",
textVersion = refs['ggtreeMBE']
)
bib_ggtree_mee2017 <- bibentry(
bibtype = "article",
title = "ggtree: an R package for visualization and annotation of phylogenetic trees with their covariates and other associated data.",
author = personList(
as.person("Guangchuang Yu"),
as.person("David Smith"),
as.person("Huachen Zhu"),
as.person("Yi Guan"),
as.person("Tommy Tsan-Yuk Lam")
),
year = "2017",
journal = "Methods in Ecology and Evolution",
volume = "8",
issue = "1",
number = "",
pages = "28-36",
doi = "10.1111/2041-210X.12628",
PMID = "",
url = "http://onlinelibrary.wiley.com/doi/10.1111/2041-210X.12628/abstract",
textVersion = refs['ggtree']
)
#' @importFrom utils bibentry
bib_shinyTempSignal_jgg2024 <- bibentry(
bibtype = "article",
title = "shinyTempSignal: an R shiny application for exploring temporal and other phylogenetic signals.",
author = c(
person("Li", "Zhan"),
person("Xiao", "Luo"),
person("Wenqin", "Xie"),
person("Xuan-An", "Zhu"),
person("Zijing", "Xie"),
person("Jianfeng", "Lin"),
person("Lin", "Li"),
person("Wenli", "Tang"),
person("Rui", "Wang"),
person("Lin", "Deng"),
person("Yufan", "Liao"),
person("Bingdong", "Liu"),
person("Yantong", "Cai"),
person("Qianwen", "Wang"),
person("Shuangbin", "Xu"),
person("Guangchuang", "Yu")
),
year = "2024",
journal = "Journal of Genetics and Genomics",
volume = "51",
issue = "7",
number = "",
pages = "762-768",
doi = "10.1016/j.jgg.2024.02.004",
PMID = "",
url = "https://www.sciencedirect.com/science/article/pii/S167385272400033X",
textVersion = refs['shinyTempSignal']
)
bib_treeio_mbe2020 <- bibentry(
bibtype = "article",
title = "treeio: an R package for phylogenetic tree input and output with richly annotated and associated data.",
author = c(
person("Li-Gen", "Wang"),
person("Tommy Tsan-Yuk", "Lam"),
person("Shuangbin", "Xu"),
person("Zehan", "Dai"),
person("Lang", "Zhou"),
person("Tingze", "Feng"),
person("Pingfan", "Guo"),
person("Casey W.", "Dunn"),
person("Bradley R.", "Jones"),
person("Tyler", "Bradley"),
person("Huachen", "Zhu"),
person("Yi", "Guan"),
person("Yong", "Jiang"),
person("Guangchuang", "Yu")
),
year = "2020",
journal = "Molecular Biology and Evolution",
volume = "37",
issue = "2",
number = "",
pages = "599-603",
doi = "10.1093/molbev/msz240",
PMID = "",
url = "",
textVersion = refs['treeio']
)
bib_ggmsa_bib2022 <- citEntry(
entry = "article",
title = "ggmsa: a visual exploration tool for multiple sequence alignment and associated data ",
author = personList(
as.person("Lang Zhou"),
as.person("Tingze Feng"),
as.person("Shuangbin Xu"),
as.person("Fangluan Gao"),
as.person("Tommy T Lam"),
as.person("Qianwen Wang"),
as.person("Tianzhi Wu"),
as.person("Huina Huang"),
as.person("Li Zhan"),
as.person("Lin Li"),
as.person("Yi Guan"),
as.person("Zehan Dai"),
as.person("Guangchuang Yu")
),
journal = "BRIEFINGS IN BIOINFORMATICS",
volume = "23",
issue = "4",
year = "2022",
month = "06",
ISSN = "1467-5463",
doi = "10.1093/bib/bbac222",
PMID = "35671504",
url = "https://academic.oup.com/bib/article-abstract/23/4/bbac222/6603927",
textVersion = refs['ggmsa']
)
yulab.utils/R/biorxiv.R 0000644 0001762 0000144 00000002647 14404503310 014536 0 ustar ligges users ## biorxiv_get_publication <- function(url) {
## # url <- "https://www.biorxiv.org/search/visualization%20numresults%3A75%20sort%3Arelevance-rank"
## x <- readLines(url)
## pub <- x[grep("/content/10.1101", x)]
## pub_url <- gsub(".*(/content/[[:digit:]\\.v/]+).*", "\\1", pub)
## pub_url <- paste0("https://www.biorxiv.org", pub_url)
## pub_title <- gsub("<[^>]+>", "", pub) %>%
## sub("^\\s+", "", .) %>%
## sub("\\s+$", "", .)
## data.frame(url = pub_url,
## title = pub_title)
## }
## biorxiv_get_correspondance <- function(url) {
## # url <- "https://www.biorxiv.org/content/10.1101/701680v3"
## x <- readLines(url)
## i <- grep("citation_author\"", x)
## j <- grep("citation_author_email", x)
## idx <- vapply(j, function(ii) {
## jj <- ii - i
## i[which(jj == min(jj[jj >0]))]
## }, numeric(1))
## author <- x[idx] %>% unique %>%
## sub(".*content=\"([^\"]+).*", "\\1", .)
## email <- x[j] %>% unique %>%
## sub(".*content=\"([^\"]+).*", "\\1", .)
## data.frame(author = author, email = email) %>% unique
## }
## url <- "https://www.biorxiv.org/search/visualization%20numresults%3A75%20sort%3Arelevance-rank"
## y <- biorxiv_get_publication(url)
## xx <- lapply(y$url, function(x) {
## cat("parsing", x, "\n")
## biorxiv_get_correspondance(x)
## })
yulab.utils/R/file.R 0000644 0001762 0000144 00000010771 15117723231 014000 0 ustar ligges users #' @rdname yread
#' @export
#' @family io-utils
yread_tsv <- function(file, reader = utils::read.delim,
params = list(),
cache_dir = tempdir()
) {
# e.g. params = list(sep = "\t", header = FALSE)
yread(file,
reader = reader,
params = params,
cache_dir = cache_dir
)
}
#' read file with caching
#'
#' This function read a file (local or url) and cache the content.
#' @title yread
#' @rdname yread
#' @param file a file or url
#' @param reader a function to read the 'file_url'
#' @param params a list of parameters that passed to the 'reader'
#' @param cache_dir a folder to store cache files. If set to NULL will disable cache.
#' @return the output of using the 'reader' to read the 'file_url' with parameters specified by the 'params'
#' @author Yonghe Xia and Guangchuang Yu
#' @importFrom fs path_join
#' @importFrom digest digest
#' @export
#' @family io-utils
yread <- function(file, reader = readLines, params = list(),
cache_dir = NULL) {
if (!is.null(cache_dir)) {
# Generate a unique cache filename based on the file URL
cache_filename <- fs::path_join(c(cache_dir, paste0(digest::digest(file), ".rds")))
} else {
cache_filename <- NULL
}
# Check if the cached file exists
if (!is.null(cache_filename) && file.exists(cache_filename)) {
# If cached file exists, load and return the cached data
cached_data <- readRDS(cache_filename)
return(cached_data)
} else {
# If cached file does not exist, read and cache the data
data <- do.call(reader, args = c(file, params))
if (!is.null(cache_filename)) {
saveRDS(data, cache_filename)
}
return(data)
}
}
#' read clipboard
#'
#'
#' @title read.cb
#' @param reader function to read the clipboard
#' @param ... parameters for the reader
#' @return clipboard content, output type depends on the output of the reader
#' @author Guangchuang Yu
#' @importFrom utils read.table
#' @export
#' @family io-utils
read.cb <- function(reader = read.table, ...) {
os <- which_os()
if (os == "Darwin") {
clip <- pipe("pbpaste")
} else {
clip <- "clipboard"
}
reader(clip, ...)
}
#' open selected directory or file
#'
#'
#' @title o
#' @param file to be open; open working directory by default
#' @return No return value, called for opening specific directory or file
#' @examples
#' \dontrun{
#' ## to open current working directory
#' o()
#' }
#' @export
#' @author Guangchuang Yu
#' @family io-utils
o <- function(file=".") {
file <- normalizePath(file)
os <- which_os()
if (is.rserver()) {
if (dir.exists(file)) {
stop("open directory in RStudio Server is not supported.")
}
rserver_ip <- getOption("rserver_ip")
if (!is.null(rserver_ip)) {
rserver_port <- getOption("rserver_port") %||% '8787'
if (!startsWith(rserver_ip, "http")) {
rserver_ip <- paste0("http://", rserver_ip)
}
utils::browseURL(
paste0(
paste(rserver_ip, rserver_port, sep=":"),
"/file_show?path=",
file
))
} else {
file.edit <- get("file.edit")
file.edit(file)
}
} else if (os == "Darwin") {
cmd <- paste("open", file)
system(cmd)
} else if (os == "Linux") {
cmd <- paste("xdg-open", file, "&")
system(cmd)
} else if (os == "Windows") {
## wd <- sub("/", "\\", getwd())
## cmd <- paste("explorer", wd)
## suppressWarnings(shell(cmd))
cmd <- paste("start", file)
shell(cmd)
}
}
is.rserver <- function(){
RStudio.Version <- tryCatch(get("RStudio.Version"), error = function(e) NULL)
if(is.null(RStudio.Version)) return(FALSE)
if(!is.function(RStudio.Version)) return(FALSE)
RStudio.Version()$mode == 'server'
}
#' Open data frame in Excel. It can be used in pipe.
#'
#'
#' @title show_in_excel
#' @param .data a data frame to be open
#' @return original .data
#' @export
#' @author Guangchuang Yu
#' @family io-utils
show_in_excel <- function(.data) {
f <- tempfile(fileext = '.csv')
utils::write.csv(.data, file=f)
o(f)
invisible(.data)
}
yulab.utils/R/sudo-install.R 0000644 0001762 0000144 00000001132 14444013464 015470 0 ustar ligges users sudo_install <- function(pkgs) {
## pkgs_str <- paste0('"', pkgs, '"') %>%
## paste(collapse=',') %>%
## paste("c(", ., ")")
## rcmd0 <- 'options(repos = c(CRAN = "https://mirrors.e-ducation.cn/CRAN/"));'
os <- Sys.info()[1]
if (os == "Windows") {
sudo <- ""
} else {
sudo <- "sudo"
}
for (pkg in pkgs) {
pkg <- paste0('"', pkg, '"')
rcmd <- paste0('install.packages(', pkg, ')')
## rcmd <- paste0(rcmd0, rcmd)
cmd <- paste0(sudo, " Rscript -e '", rcmd, "'")
system(cmd)
}
}
yulab.utils/R/install_zip.R 0000644 0001762 0000144 00000004520 15113174124 015401 0 ustar ligges users #' install github package
#'
#' it download the zip file first and use `install_zip` to install it
#' @title install_zip_gh
#' @param repo github repo
#' @param ref github branch, default is HEAD, which means the default branch of the GitHub repo
#' @param subdir sub directory that contains R package files, default is NULL
#' @param args argument to build package
#' @return No return value, called for installing github package
#' @importFrom utils download.file
#' @export
#' @author Guangchuang Yu
install_zip_gh <- function(repo, ref = "HEAD", subdir = NULL, args = "--no-build-vignettes") {
## repo <- 'GuangchuangYu/nCov2019'
url <- paste0('https://codeload.github.com/', repo, '/zip/', ref)
f <- tempfile(fileext=".zip")
mydownload(url, destfile = f)
if (!is_valid_zip(f)) {
stop("Invalid zip file downloaded, please check the 'ref' parameter to set a correct github branch.")
}
install_zip(f, subdir = subdir, args=args)
}
#' install R package from zip file of source codes
#'
#'
#' @title install_zip
#' @param file zip file
#' @param args argument to build package
#' @param subdir sub directory that contains R package files, default is NULL
#' @return No return value, called for install R package from zip file of source codes
#' @export
#' @author Guangchuang Yu
install_zip <- function(file, subdir = NULL, args = "--no-build-vignettes") {
dir <- tempfile()
utils::unzip(file, exdir=dir)
fs <- list.files(path=dir, full.names=T)
#if (length(fs) == 1 && dir.exists(fs)) {
# dir <- fs
#}
## dir <- paste0(dir, '/', basename(repo), '-master')
dir <- fs[which.max(file.info(fs)$atime)]
if (!is.null(subdir)) dir <- file.path(dir, subdir)
if ("INDEX" %in% list.files(dir)) {
# file is binary package
pkg <- file
} else {
# file is zip of package source
## remotes::install_local(path=dir, ..., force=TRUE)
## pkg <- pkgbuild::build(dir, args=args)
build <- get_fun_from_pkg('pkgbuild', 'build')
pkg <- build(dir, args=args)
}
utils::install.packages(pkg, repos=NULL)
}
is_valid_zip <- function(zipfile) {
fs <- tryCatch(utils::unzip(zipfile, list=TRUE), error = function(e) NULL)
if (is.null(fs)) return(FALSE)
return(TRUE)
}
yulab.utils/R/bib-knownledge.R 0000644 0001762 0000144 00000025164 15102535573 015756 0 ustar ligges users bib_knownledge <- function(id) {
bib <- c(
innovation2024 = bib_clusterProfiler_innovation2024,
np2024 = bib_clusterProfiler_np2024,
innovation2021 = bib_clusterProfiler_innovation2021,
omics2012 = bib_clusterProfiler_omics2012,
chipseeker2022 = bib_chipseeker_cp2022,
chipseeker2015 = bib_chipseeker_bioinfo2015,
gosemsim2020 = bib_gosemsim_mmb2020,
gosemsim2010 = bib_gosemsim_bioinfo2010,
meshes2018 = bib_meshes_bioinfo2018,
reactome2016 = bib_reactomepa_mbs20016,
dose2015 = bib_dose_bioinfo2015
)
if (!id %in% names(bib)) {
return(NULL)
}
bib[id]
}
ref_knownledge <- function() {
refs <- c(
ChIPseeker_CP = paste(
"Qianwen Wang, Ming Li, Tianzhi Wu, Li Zhan, Lin Li, Meijun Chen, Wenqin Xie, Zijing Xie, Erqiang Hu, Shuangbin Xu, Guangchuang Yu.",
"Exploring epigenomic datasets by ChIPseeker.",
"Current Protocols. 2022, 2(10): e585"
),
ChIPseeker = paste(
"Guangchuang Yu, Li-Gen Wang, and Qing-Yu He.",
"ChIPseeker: an R/Bioconductor package for ChIP peak annotation, comparison and visualization.",
"Bioinformatics. 2015, 31(14):2382-2383"
),
GOSemSim_MMB = paste(
"Guangchuang Yu.",
"Gene Ontology Semantic Similarity Analysis Using GOSemSim.",
"In: Kidder B. (eds) Stem Cell Transcriptional Networks.",
"Methods in Molecular Biology. 2020, 2117:207-215.",
"Humana, New York, NY."
),
GOSemSim = paste(
"Guangchuang Yu, Fei Li, Yide Qin, Xiaochen Bo, Yibo Wu and Shengqi Wang.",
"GOSemSim: an R package for measuring semantic similarity among GO terms and gene products.",
"Bioinformatics. 2010, 26(7):976-978"
),
DOSE = paste(
"Guangchuang Yu, Li-Gen Wang, Guang-Rong Yan, Qing-Yu He.",
"DOSE: an R/Bioconductor package for Disease Ontology Semantic and Enrichment analysis.",
"Bioinformatics. 2015, 31(4):608-609"
),
ReactomePA = paste(
"Guangchuang Yu, Qing-Yu He.",
"ReactomePA: an R/Bioconductor package for reactome pathway analysis and visualization.",
"Molecular BioSystems. 2016, 12(2):477-479"
),
clusterProfiler_NP = paste(
"S Xu, E Hu, Y Cai, Z Xie, X Luo, L Zhan, W Tang,",
"Q Wang, B Liu, R Wang, W Xie, T Wu, L Xie, G Yu.",
"Using clusterProfiler to characterize multiomics data.",
"Nature Protocols. 2024, 19(11):3292-3320"
),
clusterProfiler_Innovation2024 = paste(
"G Yu.",
"Thirteen years of clusterProfiler.",
"The Innovation. 2024, 5(6):100722"
),
clusterProfiler_Innovation = paste(
"T Wu, E Hu, S Xu, M Chen, P Guo, Z Dai, T Feng, L Zhou,",
"W Tang, L Zhan, X Fu, S Liu, X Bo, and G Yu.",
"clusterProfiler 4.0: A universal enrichment tool for interpreting omics data.",
"The Innovation. 2021, 2(3):100141"
),
clusterProfiler = paste(
"Guangchuang Yu, Li-Gen Wang, Yanyan Han and Qing-Yu He.",
"clusterProfiler: an R package for comparing biological themes among gene clusters.",
"OMICS: A Journal of Integrative Biology. 2012, 16(5):284-287"
),
meshes = paste(
"Guangchuang Yu.",
"Using meshes for MeSH term enrichment and semantic analyses.",
"Bioinformatics. 2018, 34(21):3766-3767, doi:10.1093/bioinformatics/bty410"
)
)
return(refs)
}
ref2 <- ref_knownledge()
bib_clusterProfiler_innovation2024 <- citEntry(
entry = "ARTICLE",
title = "Thirteen years of clusterProfiler",
author = c(person("Guangchuang", "Yu")),
url = "https://doi.org/10.1016/j.xinn.2024.100722",
doi = "10.1016/j.xinn.2024.100722",
journal = "The Innovation",
month = "Nov",
year = "2024",
volume = "5",
number = "6",
pages = "100722",
textVersion = ref2['clusterProfiler_Innovation2024']
)
bib_clusterProfiler_np2024 <- citEntry(
entry = "ARTICLE",
title = "Using clusterProfiler to characterize multiomics data",
author = c(
person("Shuangbin", "Xu"),
person("Erqiang", "Hu"),
person("Yantong", "Cai"),
person("Zijing", "Xie"),
person("Xiao", "Luo"),
person("Li", "Zhan"),
person("Wenli", "Tang"),
person("Qianwen", "Wang"),
person("Bingdong", "Liu"),
person("Rui", "Wang"),
person("Wenqin", "Xie"),
person("Tianzhi", "Wu"),
person("Liwei", "Xie"),
person("Guangchuang", "Yu")
),
issn = "1750-2799",
url = "https://www.nature.com/articles/s41596-024-01020-z",
doi = "10.1038/s41596-024-01020-z",
journal = "Nature Protocols",
month = "Nov",
year = "2024",
volume = "19",
number = "11",
pages = "3292-3320",
textVersion = ref2['clusterProfiler_NP']
)
bib_clusterProfiler_innovation2021 <- citEntry(
entry = "ARTICLE",
title = "clusterProfiler 4.0: A universal enrichment tool for interpreting omics data",
author = c(
person("Tianzhi", "Wu"),
person("Erqiang", "Hu"),
person("Shuangbin", "Xu"),
person("Meijun", "Chen"),
person("Pingfan", "Guo"),
person("Zehan", "Dai"),
person("Tingze", "Feng"),
person("Lang", "Zhou"),
person("Wenli", "Tang"),
person("Li", "Zhan"),
person("xiaochong", "Fu"),
person("Shanshan", "Liu"),
person("Xiaochen", "Bo"),
person("Guangchuang", "Yu")
),
journal = "The Innovation",
year = "2021",
volume = "2",
number = "3",
pages = "100141",
PMID = "",
doi = "10.1016/j.xinn.2021.100141",
textVersion = ref2['clusterProfiler_Innovation']
)
bib_clusterProfiler_omics2012 <- citEntry(
entry = "ARTICLE",
title = "clusterProfiler: an R package for comparing biological themes among gene clusters",
author = personList(
as.person("Guangchuang Yu"),
as.person("Li-Gen Wang"),
as.person("Yanyan Han"),
as.person("Qing-Yu He")
),
journal = "OMICS: A Journal of Integrative Biology",
year = "2012",
volume = "16",
number = "5",
pages = "284-287",
PMID = "22455463",
doi = "10.1089/omi.2011.0118",
textVersion = ref2['clusterProfiler']
)
bib_meshes_bioinfo2018 <- citEntry(
entry = "ARTICLE",
title = "Using meshes for MeSH term enrichment and semantic analyses ",
author = as.person("Guangchuang Yu"),
journal = "Bioinformatics",
year = "2018",
volume = "34",
number = "21",
pages = "3766-3767",
PMID = "29790928",
doi = "10.1093/bioinformatics/bty410",
textVersion = ref2["meshes"]
)
bib_reactomepa_mbs20016 <- citEntry(
entry = "ARTICLE",
title = "ReactomePA: an R/Bioconductor package for reactome pathway analysis and visualization",
author = c(
person("Guangchuang", "Yu"),
person("Qing-Yu", "He")
),
journal = "Molecular BioSystems",
year = "2016",
volume = "12",
number = "12",
pages = "477-479",
PMID = "26661513",
url = "http://pubs.rsc.org/en/Content/ArticleLanding/2015/MB/C5MB00663E",
doi = "10.1039/C5MB00663E",
textVersion = ref2['ReactomePA']
)
bib_dose_bioinfo2015 <- citEntry(
entry = "ARTICLE",
title = "DOSE: an R/Bioconductor package for Disease Ontology Semantic and Enrichment analysis",
author = c(
person("Guangchuang", "Yu"),
person("Li-Gen", "Wang"),
person("Guang-Rong", "Yan"),
person("Qing-Yu", "He")
),
journal = "Bioinformatics",
year = "2015",
volume = "31",
number = "4",
pages = "608-609",
PMID = "",
url = "http://bioinformatics.oxfordjournals.org/content/31/4/608",
doi = "10.1093/bioinformatics/btu684",
textVersion = ref2['DOSE']
)
bib_chipseeker_cp2022 <- citEntry(
entry = "ARTICLE",
title = "Exploring epigenomic datasets by ChIPseeker",
author = c(
person("Qianwen", "Wang"),
person("Ming", "Li"),
person("Tianzhi", "Wu"),
person("Li", "Zhan"),
person("Lin", "Li"),
person("Meijun", "Chen"),
person("Wenqin", "Xie"),
person("Zijing", "Xie"),
person("Erqiang", "Hu"),
person("Shuangbin", "Xu"),
person("Guangchuang", "Yu", email = "guangchuangyu@gmail.com")
),
journal = "Current Protocols",
year = "2022",
volume = "2",
number = "10",
pages = "e585",
PMID = "36286622",
doi = "10.1002/cpz1.585",
url = "https://onlinelibrary.wiley.com/share/author/GYJGUBYCTRMYJFN2JFZZ?target=10.1002/cpz1.585",
textVersion = ref2['ChIPseeker_CP']
)
bib_chipseeker_bioinfo2015 <- citEntry(
entry = "ARTICLE",
title = "ChIPseeker: an R/Bioconductor package for ChIP peak annotation, comparison and visualization",
author = personList(
as.person("Guangchuang Yu"),
as.person("Li-Gen Wang"),
as.person("Qing-Yu He")
),
journal = "Bioinformatics",
year = "2015",
volume = "31",
number = "14",
pages = "2382-2383",
PMID = "25765347",
doi = "10.1093/bioinformatics/btv145",
textVersion = ref2['ChIPseeker']
)
bib_gosemsim_mmb2020 <- citEntry(
entry = "ARTICLE",
title = "Gene Ontology Semantic Similarity Analysis Using GOSemSim",
author = person("Guangchuang", "Yu"),
journal = "Methods in Molecular Biology",
shortjournal = "Methods Mol. Biol.",
year = "2020",
volume = "2117",
pages = "207-215",
PMID = "31960380",
issn = "1940-6029",
doi = "10.1007/978-1-0716-0301-7_11",
textVersion = ref2['GOSemSim_MMB']
)
bib_gosemsim_bioinfo2010 <- citEntry(
entry = "ARTICLE",
title = "GOSemSim: an R package for measuring semantic similarity among GO terms and gene products",
author = personList(
as.person("Guangchuang Yu"),
as.person("Fei Li"),
as.person("Yide Qin"),
as.person("Xiaochen Bo"),
as.person("Yibo Wu"),
as.person("Shengqi Wang")
),
journal = "Bioinformatics",
year = "2010",
volume = "26",
number = "7",
pages = "976-978",
PMID = "20179076",
doi = "10.1093/bioinformatics/btq064",
textVersion = ref2['GOSemSim']
)
yulab.utils/R/utilities.R 0000644 0001762 0000144 00000002540 15115330064 015063 0 ustar ligges users `%||%` <- function(a, b) if (is.null(a)) b else a
.hi <- function(package = NULL, n=2L) {
env <- sys.parent(n)
if (!is.null(env)) {
caller <- deparse(sys.call(env))
caller <- sub("(\\w+)\\(.*", "\\1", caller)
if (is.null(package)) return(FALSE)
if (get_caller_package(caller) %in% package) return(TRUE)
}
return(FALSE)
}
get_caller_package <- function(caller) {
if (is.character(caller)) {
fn <- tryCatch(get(caller, mode = "function"), error = function(e) NULL)
if (is.null(fn)) return("")
} else {
fn <- caller
}
environmentName(environment(fn))
}
.called_by_package <- function(package) {
call_stack <- sys.calls()
pattern <- sprintf("^package:%s", package)
for (call in call_stack) {
call <- as.character(as.expression(call))
if (grepl(pattern, call)) {
return(TRUE)
}
}
return(FALSE)
}
assert_single_string <- function(x, name) {
if (!is.character(x) || length(x) != 1 || x == "") {
yulab_abort(sprintf("%s must be a single non-empty character string", name), class = "parameter_error")
}
invisible(TRUE)
}
normalize_path2 <- function(path) {
normalizePath(path, winslash = "/", mustWork = FALSE)
}
has_permission <- function(path, mode) {
file.access(path, mode) == 0
}
yulab.utils/R/error-utils.r 0000644 0001762 0000144 00000030661 15117723164 015415 0 ustar ligges users
#' Standardized error handling
#'
#' Provides `rlang`-based wrappers for messaging: `yulab_abort()`, `yulab_warn()`,
#' and `yulab_inform()`.
#'
#' @param message Message string
#' @param class Custom class for categorization
#' @param ... Additional context
#' @return No return value
#' @importFrom rlang abort
#' @rdname yulab-message
#' @export
#' @family messages
yulab_abort <- function(message, class = "yulab_error", ...) {
abort(
message = message,
class = c(class, "yulab_error"),
...
)
}
#' @importFrom rlang warn
#' @rdname yulab-message
#' @export
yulab_warn <- function(message, class = "yulab_warning", ...) {
warn(
message = message,
class = c(class, "yulab_warning"),
...
)
}
#' @importFrom rlang inform
#' @rdname yulab-message
#' @export
yulab_inform <- function(message, class = "yulab_info", ...) {
inform(
message = message,
class = c(class, "yulab_info"),
...
)
}
#' Validate input with type/length constraints
#'
#' Enhanced input validation supporting base types and class checks.
#' @param x Object to check
#' @param type Expected type (e.g., `"numeric"`, `"character"`, or class name)
#' @param length Expected length
#' @param min_length Minimum length
#' @param max_length Maximum length
#' @param allow_null Whether `NULL` is allowed
#' @param arg_name Argument name for messages
#' @return Invisible `TRUE` on success
#' @export
#' @family validate-utils
check_input <- function(x, type = NULL, length = NULL, min_length = NULL,
max_length = NULL, allow_null = FALSE, arg_name = "input") {
# Validate function parameters
assert_single_string(arg_name, "arg_name")
if (!is.null(type) && (!is.character(type) || length(type) != 1)) {
yulab_abort("type must be a single character string or NULL", class = "parameter_error")
}
if (!is.null(length) && (!is.numeric(length) || length(length) != 1 || length <= 0)) {
yulab_abort("length must be a single positive number or NULL", class = "parameter_error")
}
if (!is.null(min_length) && (!is.numeric(min_length) || length(min_length) != 1 || min_length < 0)) {
yulab_abort("min_length must be a single non-negative number or NULL", class = "parameter_error")
}
if (!is.null(max_length) && (!is.numeric(max_length) || length(max_length) != 1 || max_length <= 0)) {
yulab_abort("max_length must be a single positive number or NULL", class = "parameter_error")
}
# Check for NULL values
if (allow_null && is.null(x)) {
return(invisible(TRUE))
}
if (is.null(x)) {
yulab_abort(
paste0("Invalid ", arg_name, ": cannot be NULL"),
class = "null_error"
)
}
# Enhanced type checking with support for basic types
if (!is.null(type)) {
# Check for basic types first
basic_types <- c("numeric", "character", "logical", "integer", "double", "complex", "raw")
if (type %in% basic_types) {
if (typeof(x) != type) {
yulab_abort(
paste0("Invalid ", arg_name, ": expected ", type, ", got ", typeof(x)),
class = "type_error"
)
}
} else {
# Check for S3/S4 classes
if (!inherits(x, type)) {
yulab_abort(
paste0("Invalid ", arg_name, ": expected ", type, ", got ", class(x)[1]),
class = "type_error"
)
}
}
}
# Length validation
x_length <- length(x)
if (!is.null(length) && x_length != length) {
yulab_abort(
paste0("Invalid ", arg_name, ": expected length ", length, ", got ", x_length),
class = "length_error"
)
}
if (!is.null(min_length) && x_length < min_length) {
yulab_abort(
paste0("Invalid ", arg_name, ": minimum length is ", min_length, ", got ", x_length),
class = "length_error"
)
}
if (!is.null(max_length) && x_length > max_length) {
yulab_abort(
paste0("Invalid ", arg_name, ": maximum length is ", max_length, ", got ", x_length),
class = "length_error"
)
}
invisible(TRUE)
}
#' Check if required packages are installed with informative errors
#'
#' Enhanced package checking with better error messages and validation
#' @rdname check_packages
#' @param packages Character vector of package names
#' @param reason Reason why these packages are needed
#' @return Invisible TRUE if all packages are available, throws error otherwise
#' @export
#' @family validate-utils
check_packages <- function(packages, reason = "for this functionality") {
# Validate input parameters
if (!is.character(packages) || length(packages) == 0) {
yulab_abort("packages must be a non-empty character vector", class = "parameter_error")
}
if (is.null(reason)) {
call <- sys.call(1L)
reason <- sprintf("for %s()", as.character(call)[1])
}
if (!is.character(reason) || length(reason) != 1) {
yulab_abort("reason must be a single character string", class = "parameter_error")
}
# Remove duplicates and empty strings
packages <- unique(packages[packages != ""])
if (length(packages) == 0) {
yulab_warn("No valid package names provided", class = "empty_package_list_warning")
return(invisible(TRUE))
}
# Check for missing packages
# missing_pkgs <- packages[!sapply(packages, requireNamespace, quietly = TRUE)]
missing_pkgs <- packages[!vapply(packages, is.installed, logical(1))]
if (length(missing_pkgs) > 0) {
pkg_list <- paste(missing_pkgs, collapse = ", ")
yulab_abort(
paste0("Missing required packages ", reason, ": ", pkg_list, ". ",
"Please install with: install.packages(c(",
paste0("\"", missing_pkgs, "\"", collapse = ", "), "))"),
class = "missing_package_error"
)
}
invisible(TRUE)
}
#' @rdname check_packages
#' @export
check_pkg <- check_packages
#' Handle file operations with proper error messages
#'
#' Enhanced file validation with comprehensive checks and better error messages
#' @param path File path
#' @param operation Operation being performed (read, write, etc.)
#' @param must_exist Whether the file must exist
#' @return Invisible TRUE if operation can proceed, throws error otherwise
#' @export
#' @family validate-utils
check_file <- function(path, operation = "read", must_exist = TRUE) {
assert_single_string(path, "path")
assert_single_string(operation, "operation")
normalized_path <- normalize_path2(path)
if (must_exist) {
if (!file.exists(path)) {
yulab_abort(
paste0("File not found for ", operation, ": ", normalized_path),
class = "file_not_found_error"
)
}
if (grepl("read", operation, ignore.case = TRUE)) {
if (!has_permission(path, 4)) {
yulab_abort(
paste0("No read permission for file: ", normalized_path),
class = "file_permission_error"
)
}
}
} else {
# For files that shouldn't exist (e.g., write operations)
if (file.exists(path)) {
yulab_warn(
paste0("File already exists and will be overwritten: ", normalized_path),
class = "file_overwrite_warning"
)
if (!has_permission(path, 2)) {
yulab_abort(
paste0("No write permission for existing file: ", normalized_path),
class = "file_permission_error"
)
}
}
}
invisible(TRUE)
}
#' Check if value is within specified range
#'
#' Validates that a numeric value falls within the specified range
#' @param x Numeric value to check
#' @param min Minimum allowed value (optional)
#' @param max Maximum allowed value (optional)
#' @param inclusive Whether bounds are inclusive (default: TRUE)
#' @param arg_name Name of the argument for error messages
#' @return Invisible TRUE if valid, throws error otherwise
#' @export
#' @family validate-utils
check_range <- function(x, min = NULL, max = NULL, inclusive = TRUE, arg_name = "value") {
# Validate parameters
if (!is.numeric(x) || length(x) != 1) {
yulab_abort(paste0(arg_name, " must be a single numeric value"), class = "parameter_error")
}
if (!is.null(min) && (!is.numeric(min) || length(min) != 1)) {
yulab_abort("min must be a single numeric value or NULL", class = "parameter_error")
}
if (!is.null(max) && (!is.numeric(max) || length(max) != 1)) {
yulab_abort("max must be a single numeric value or NULL", class = "parameter_error")
}
if (!is.logical(inclusive) || length(inclusive) != 1) {
yulab_abort("inclusive must be a single logical value", class = "parameter_error")
}
# Range validation
if (!is.null(min)) {
if (inclusive && x < min) {
yulab_abort(
paste0("Invalid ", arg_name, ": minimum value is ", min, ", got ", x),
class = "range_error"
)
} else if (!inclusive && x <= min) {
yulab_abort(
paste0("Invalid ", arg_name, ": must be greater than ", min, ", got ", x),
class = "range_error"
)
}
}
if (!is.null(max)) {
if (inclusive && x > max) {
yulab_abort(
paste0("Invalid ", arg_name, ": maximum value is ", max, ", got ", x),
class = "range_error"
)
} else if (!inclusive && x >= max) {
yulab_abort(
paste0("Invalid ", arg_name, ": must be less than ", max, ", got ", x),
class = "range_error"
)
}
}
invisible(TRUE)
}
#' Check if directory exists and is accessible
#'
#' Validates directory existence and accessibility with options to create if missing
#' @param path Directory path
#' @param create_if_missing Whether to create directory if it doesn't exist
#' @param check_write_permission Whether to verify write permissions
#' @param arg_name Name of the argument for error messages
#' @return Invisible TRUE if valid, throws error otherwise
#' @export
#' @family validate-utils
check_directory <- function(path, create_if_missing = FALSE, check_write_permission = TRUE, arg_name = "directory") {
assert_single_string(path, "path")
if (!is.logical(create_if_missing) || length(create_if_missing) != 1) {
yulab_abort("create_if_missing must be a single logical value", class = "parameter_error")
}
if (!is.logical(check_write_permission) || length(check_write_permission) != 1) {
yulab_abort("check_write_permission must be a single logical value", class = "parameter_error")
}
normalized_path <- normalize_path2(path)
if (!dir.exists(path)) {
if (create_if_missing) {
# Attempt to create directory
dir_created <- tryCatch({
dir.create(path, recursive = TRUE, showWarnings = FALSE)
TRUE
}, error = function(e) FALSE)
if (!dir_created) {
yulab_abort(
paste0("Failed to create directory: ", normalized_path),
class = "directory_creation_error"
)
}
yulab_inform(paste0("Created directory: ", normalized_path), class = "directory_created_info")
} else {
yulab_abort(
paste0("Directory does not exist: ", normalized_path),
class = "directory_not_found_error"
)
}
}
if (check_write_permission) {
if (!has_permission(path, 2)) {
yulab_abort(
paste0("No write permission for directory: ", normalized_path),
class = "directory_permission_error"
)
}
}
invisible(TRUE)
}
yulab.utils/R/zzz.R 0000644 0001762 0000144 00000000341 14651121636 013711 0 ustar ligges users ## @importFrom memoise memoise
.onLoad <- function(libname, pkgname) {
# yread <<- memoise::memoise(yread)
# yread_tsv <<- memoise::memoise(yread_tsv)
# packageStartupMessage(yulab_msg(pkgname))
}
yulab.utils/R/scale.R 0000644 0001762 0000144 00000000556 15113174111 014141 0 ustar ligges users #' normalized data by range
#'
#'
#' @title scale-range
#' @param data the input data.
#' @return normalized data
#' @export
#' @author Guangchuang Yu
scale_range <- function(data) {
normalized_data <- apply(data, 2, function(x) {
(x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
})
as.data.frame(normalized_data)
}
yulab.utils/R/yulab-utils-package.R 0000644 0001762 0000144 00000000045 14560213723 016716 0 ustar ligges users #' @keywords internal
"_PACKAGE"
yulab.utils/R/matrix-utils.R 0000644 0001762 0000144 00000001664 15113174121 015516 0 ustar ligges users #' convert a matrix to a tidy data frame
#' (from wide to long format as described in the tidyverse concept)
#'
#'
#' @title mat2df
#' @param x the input matrix
#' @return a data.frame in long format with the 'value' column stores the original values
#' and 'row' and 'col' columns stored in row and column index as in x
#' @examples
#' x <- matrix(1:15, nrow = 3)
#' mat2df(x)
#' @export
#' @author Guangchuang Yu
mat2df <- function(x) {
nr <- nrow(x)
nc <- ncol(x)
d <- data.frame(
value = as.vector(x),
row = rep(1:nr, times = nc),
col = rep(1:nc, each = nr)
)
return(d)
}
#' convert a matrix to a list
#'
#'
#' @title mat2list
#' @param x the input matrix
#' @return a list that contains matrix columns as its elements
#' @examples
#' x <- matrix(1:15, nrow = 3)
#' mat2list(x)
#' @export
mat2list <- function(x){
lapply(seq_len(ncol(x)), function(i) x[,i])
}
yulab.utils/R/quiet.r 0000644 0001762 0000144 00000000531 15116450203 014234 0 ustar ligges users #' Suppress messages and output from `x`
#' @title quiet
#' @param x some code
#' @return the result of `x`
#' @importFrom utils capture.output
#' @export
quiet <- function(x) {
res <- suppressMessages({
out <- NULL
capture.output({
out <- force(x)
}, file = NULL)
out
})
invisible(res)
}
yulab.utils/R/concat.r 0000644 0001762 0000144 00000004563 14723520003 014364 0 ustar ligges users #' chunked array
#'
#' concate two vector/chunked_array into a chunked_array object
#' @title c2
#' @param x a vector or chunked_array object
#' @param y a vector or chunked_array object
#' @return chunked_array object
#' @author Guangchuang Yu
#' @export
c2 <- function(x, y) {
if (length(x) == 0) return(y)
if (length(y) == 0) return(x)
same_mode <- (is.numeric(x) && is.numeric(y)) ||
(is.character(x) && is.character(y))
if (!same_mode) stop("x and y should be both numeric or character vector.")
X <- as_chunked_array(x)
Y <- as_chunked_array(y)
res <- structure(
list(
vector_list = c(X$vector_list, Y$vector_list),
idx = c(X$idx, Y$idx + length(X))
),
class = "chunked_array"
)
return(res)
}
as_chunked_array <- function(x) {
if (inherits(x, "chunked_array")) return(x)
if (!is.numeric(x) && !is.character(x)) {
stop("only numeric/character vector supported")
}
structure(
list(
vector_list = list(x),
idx = 0
),
class = "chunked_array"
)
}
#' @method as.vector chunked_array
#' @export
as.vector.chunked_array <- function(x, mode = "any") {
unlist(x$vector_list)
}
#' @method print chunked_array
#' @export
print.chunked_array <- function(x, ...) {
n <- length(x)
msg <- sprintf("chunked array with size of %d\n", n)
cat(msg)
}
#' @method length chunked_array
#' @export
length.chunked_array <- function(x) {
last_item(x$idx) + length(last_item(x$vector_list))
}
last_item <- function(x) {
if (is.list(x)) return(x[[length(x)]])
x[length(x)]
}
#' @method [ chunked_array
#' @export
`[.chunked_array` <- function(x, i, ...) {
# array_idx <- vapply(i, \(ii) last_item(which(ii > x$idx)), numeric(1))
#
# pos <- i - x$idx[array_idx]
#
# output <- ifelse(is.numeric(x), numeric(1), character(1))
# vapply(seq_along(i), \(j) x$vector_list[[array_idx[j]]][pos[j]], output)
as.vector(x)[i] # faster :)
}
#' @method is.numeric chunked_array
#' @export
is.numeric.chunked_array <- function(x) {
is.numeric(x$vector_list[[1]])
}
#' @method is.character chunked_array
#' @export
is.character.chunked_array <- function(x) {
is.character(x$vector_list[[1]])
}
yulab.utils/R/parse_ratio.R 0000644 0001762 0000144 00000001174 15115415657 015376 0 ustar ligges users ##' Parse character ratio to double, e.g., `1/5` → `0.2`
##'
##'
##' @title parse_ratio
##' @param ratio Character vector of ratios
##' @return Numeric vector
##' @export
##' @author Guangchuang Yu
parse_ratio <- function(ratio) {
x <- as.character(ratio)
x <- sub("^\\s*", "", x)
x <- sub("\\s*$", "", x)
suppressWarnings({
numerator <- as.numeric(sub("/\\s*\\d+$", "", x))
denominator <- as.numeric(sub("^\\s*\\d+\\s*/\\s*", "", x))
})
bad <- is.na(numerator) | is.na(denominator) | denominator == 0
res <- numerator/denominator
res[bad] <- NA_real_
res
}
yulab.utils/R/regexpr.R 0000644 0001762 0000144 00000003474 15117723340 014540 0 ustar ligges users #' @rdname regexpr-style
#' @export
#' @family regex-utils
set_PCRE <- function() {
options(regexpr_use_perl = TRUE)
}
#' @rdname regexpr-style
#' @export
#' @family regex-utils
set_TRE <- function() {
options(regexpr_use_perl = FALSE)
}
#' @rdname regexpr-style
#' @export
#' @family regex-utils
use_perl <- function() {
res <- getOption("regexpr_use_perl", default = auto_set_regexpr_style())
return(res)
}
#' Switch regular expression style (PCRE vs TRE)
#'
#' - `set_regexpr_style()` selects the style explicitly.
#' - `auto_set_regexpr_style()` chooses based on OS (TRE on Windows; PCRE elsewhere).
#' - `set_PCRE()` and `set_TRE()` force the style.
#'
#' These functions do not change the behavior of `gsub()`/`regexpr()` directly.
#' They set a global option that you can read via `use_perl()` and pass to `gsub()`/`regexpr()`.
#'
#' @rdname regexpr-style
#' @param style one of 'PCRE' or 'TRE'
#' @return Logical indicating whether to use `perl`
#' @references https://stackoverflow.com/questions/47240375/regular-expressions-in-base-r-perl-true-vs-the-default-pcre-vs-tre
#' @export
#' @author Guangchuang Yu
#' @family regex-utils
set_regexpr_style <- function(style) {
if (missing(style)) {
message("style is not specific, set automatically.")
auto_set_regexpr_style()
} else {
style <- match.arg(style, c("PCRE", "TRE"))
if (style == "PCRE") {
set_PCRE()
} else {
set_TRE()
}
}
res <- getOption("regexpr_use_perl")
invisible(res)
}
#' @rdname regexpr-style
#' @export
auto_set_regexpr_style <- function() {
if (which_os() == "Windows") {
set_TRE()
res <- FALSE
} else {
set_PCRE()
res <- TRUE
}
invisible(res)
}
yulab.utils/R/load-orgdb.r 0000644 0001762 0000144 00000000777 15115206073 015136 0 ustar ligges users #' load OrgDb
#'
#'
#' @title load_OrgDb
#' @param OrgDb OrgDb object or OrgDb name
#' @return OrgDb object
#' @importFrom methods is
#' @importFrom utils getFromNamespace
#' @export
#' @author Guangchuang Yu \url{https://yulab-smu.top}
load_OrgDb <- function(OrgDb) {
if (is.character(OrgDb)) {
check_packages(OrgDb, "for `load_OrgDb()`")
# OrgDb <- utils::getFromNamespace(OrgDb, OrgDb)
OrgDb <- get(OrgDb, envir = asNamespace(OrgDb))
}
return(OrgDb)
}
yulab.utils/R/scihub-dl.R 0000644 0001762 0000144 00000001573 15116451000 014722 0 ustar ligges users #' download publication via scihub
#'
#' using scihub to download publication using doi
#' @rdname scihub-dl
#' @name scihub_dl
#' @param doi doi
#' @param scihub scihub website
#' @param download whether download the pdf file
#' @return pdf url
#' @author Guangchuang Yu
#' @export
scihub_dl <- function(doi, scihub = 'sci-hub.tw', download=TRUE) {
url <- paste0('https://', scihub, '/', doi)
if (!has_internet()) return(invisible(NA_character_))
x <- tryCatch(readLines(url, warn = FALSE), error = function(e) character())
i <- grep('id = "pdf"', x)
if (!length(i)) return(invisible(NA_character_))
pdf_url <- sub(".*(//.*\\.pdf).*", "https:\\1", x[i])
if (download) {
outfile <- sub(".*/", "", pdf_url)
utils::download.file(pdf_url, destfile = outfile, quiet = TRUE, mode = "wb")
}
invisible(pdf_url)
}
yulab.utils/R/str-utils.R 0000644 0001762 0000144 00000006233 15115331154 015022 0 ustar ligges users #' Wrap long strings to multiple lines
#' @family str-utils
#'
#'
#' @title str_wrap
#' @param string Input string
#' @param width Maximum characters before wrapping
#' @return Updated strings with `"\n"` inserted
#' @export
#' @author Guangchuang Yu
str_wrap <- function(string, width = getOption("width")) {
result <- vapply(string,
FUN = function(st) {
if (!is.numeric(width) || length(width) != 1 || width < 1) {
return(st)
}
words <- list()
i <- 1
while (nchar(st) > width) {
if (!grepl(pattern = " ", x = st, perl = use_perl())) break
y <- gregexpr(pattern = ' ', text = st, perl = use_perl())
y <- y[[1]]
n <- nchar(st)
y <- c(y,n)
idx <- which(y < width)
# When the length of first word > width
if (length(idx) == 0) idx <- 1
# Split the string into two pieces
# The length of first piece is small than width
words[[i]] <- substring(st, 1, y[idx[length(idx)]] - 1)
st <- substring(st, y[idx[length(idx)]] + 1, n)
i <- i + 1
}
words[[i]] <- st
paste0(unlist(words), collapse="\n")
},
FUN.VALUE = character(1)
)
names(result) <- NULL
result
}
#' Detect patterns at the beginning or end of strings
#' @family str-utils
#'
#'
#' @title str_starts
#' @rdname str-starts-ends
#' @param string Input string
#' @param pattern Pattern to match
#' @param negate If `TRUE`, return non-matching elements
#' @return a logical vector
#' @export
#' @author Guangchuang Yu
str_starts <- function(string, pattern, negate=FALSE) {
pattern <- paste0('^', pattern)
str_detect(string, pattern, negate)
}
#' @rdname str-starts-ends
#' @export
str_ends <- function(string, pattern, negate=FALSE) {
pattern <- paste0(pattern, '$')
str_detect(string, pattern, negate)
}
#' Detect presence/absence of a match
#' @family str-utils
#'
#'
#' @title str_detect
#' @rdname str-detect
#' @param string Input string
#' @param pattern Pattern to look for
#' @param negate If `TRUE`, invert the result
#' @return Logical vector
#' @export
#' @author Guangchuang Yu
str_detect <- function(string, pattern, negate = FALSE) {
## faster than stringr::str_detect
res <- grepl(pattern = pattern, x = string, perl = use_perl())
if (negate) res <- !res
return(res)
}
#' Extract a substring using a pattern
#' @family str-utils
#'
#'
#' @title str_extract
#' @rdname str-extract
#' @param string Input string
#' @param pattern Regular expression to extract
#' @return Substring
#' @export
#' @author Guangchuang Yu
str_extract <- function(string, pattern) {
i <- regexpr(pattern = pattern, text = string, perl = use_perl())
j <- attr(i, 'match.length')
res <- substring(string, i, i+j-1)
res[res == ""] <- NA
return(res)
}
yulab.utils/R/yulab-msg.R 0000644 0001762 0000144 00000005514 15115330657 014764 0 ustar ligges users #' Messages for YuLab packages
#'
#'
#' @title yulab_msg
#' @param pkgname Package name
#' @param n Number of citation messages
#' @return Package message
#' @export
#' @author Guangchuang Yu
yulab_msg <- function(pkgname = NULL, n = 1) {
pkgs_knownledge <- c("GOSemSim",
"DOSE",
"clusterProfiler",
"meshes",
"ReactomePA",
"MicrobiomeProfiler",
"enrichplot",
"ChIPseeker")
pkgs_tree <- c("tidytree",
"treeio",
"ggtree",
"ggtreeExtra",
"ggtreeSpace",
"shinyTempSignal")
if (pkgname %in% pkgs_knownledge) {
id <- 1
} else if (pkgname %in% pkgs_tree) {
id <- 2
} else {
id <- 3
}
header_msg <- yulab_msg_header(pkgname, id)
if (id == 1) {
citation_msg <- random_ref(pkgname, ref_knownledge(), random_n = n)
} else if (id == 2) {
citation_msg <- random_ref(pkgname, ref_ggtree(), random_n = n)
} else {
citation_msg <- pkg_ref(pkgname)
}
if (is.null(citation_msg)) return(header_msg)
sprintf("%s%s", header_msg, citation_msg)
}
#' @importFrom utils packageDescription
yulab_msg_header <- function(pkgname = NULL, id = 3) {
if (is.null(pkgname)) return(NULL)
pages <- c("contribution-knowledge-mining/",
"contribution-tree-data/",
"")
urls <- sprintf("https://yulab-smu.top/%s", pages)
pkgVersion <- packageDescription(pkgname, fields = "Version")
sprintf("%s v%s Learn more at %s\n\n", pkgname, pkgVersion, urls[id])
}
random_ref <- function(pkgname, refs, random_n) {
msg <- "Please cite:\n\n"
indx <- grep(pkgname, names(refs))
if (length(indx) == 0) {
refs <- sample(refs, random_n)
} else if (length(indx) > random_n) {
refs <- sample(refs[indx], random_n)
} else {
refs <- c(refs[indx], sample(refs[-indx], random_n - length(indx)))
}
refs <- paste0(refs, collapse="\n")
if (nchar(refs) <= 0) return(NULL)
paste(strwrap(paste0(msg, refs)), collapse = "\n")
}
pkg_ref <- function(pkgname) {
refs <- c(
fanyi =
paste("D Wang, G Chen, L Li, S Wen, Z Xie, X Luo, L Zhan, S Xu, J Li, R Wang, Q Wang, G Yu.",
"Reducing language barriers, promoting information absorption, and communication using fanyi.",
"Chinese Medical Journal. 2024, 137(16):1950-1956. doi: 10.1097/CM9.0000000000003242")
)
ref <- refs[pkgname]
if (is.null(ref) || is.na(ref)) return(NULL)
msg <- "Please cite:\n\n"
str_wrap(paste0(msg, ref, "\n"))
}
yulab.utils/NAMESPACE 0000644 0001762 0000144 00000004316 15117720067 013756 0 ustar ligges users # Generated by roxygen2: do not edit by hand
S3method("[",chunked_array)
S3method(as.vector,chunked_array)
S3method(is.character,chunked_array)
S3method(is.numeric,chunked_array)
S3method(length,chunked_array)
S3method(print,chunked_array)
S3method(print,exec)
export(Biocpkg)
export(CRANpkg)
export(Githubpkg)
export(auto_set_regexpr_style)
export(c2)
export(cache_list_items)
export(cache_load)
export(cache_save)
export(cache_size)
export(check_directory)
export(check_file)
export(check_input)
export(check_packages)
export(check_pkg)
export(check_range)
export(combinations)
export(download_yulab_file)
export(exec)
export(get_cache)
export(get_cache_element)
export(get_cache_item)
export(get_dependencies)
export(get_fun_from_pkg)
export(has_internet)
export(initial_cache)
export(initial_cache_item)
export(install_zip)
export(install_zip_gh)
export(is.installed)
export(load_OrgDb)
export(ls2df)
export(mat2df)
export(mat2list)
export(mypkg)
export(o)
export(packageTitle)
export(parse_ratio)
export(pload)
export(prune_cache_item)
export(quiet)
export(rbindlist)
export(read.cb)
export(rm_cache)
export(rm_cache_item)
export(scale_range)
export(scihub_dl)
export(set_PCRE)
export(set_TRE)
export(set_regexpr_style)
export(show_in_excel)
export(str_detect)
export(str_ends)
export(str_extract)
export(str_starts)
export(str_wrap)
export(update_cache_item)
export(use_perl)
export(user_dir)
export(with_cache)
export(yread)
export(yread_tsv)
export(yulab_abort)
export(yulab_inform)
export(yulab_msg)
export(yulab_warn)
importFrom(cli,cli_h2)
importFrom(digest,digest)
importFrom(fs,path_join)
importFrom(methods,is)
importFrom(rappdirs,user_data_dir)
importFrom(rlang,abort)
importFrom(rlang,as_name)
importFrom(rlang,check_installed)
importFrom(rlang,enquo)
importFrom(rlang,inform)
importFrom(rlang,warn)
importFrom(stats,setNames)
importFrom(tools,package_dependencies)
importFrom(utils,bibentry)
importFrom(utils,capture.output)
importFrom(utils,combn)
importFrom(utils,download.file)
importFrom(utils,getFromNamespace)
importFrom(utils,modifyList)
importFrom(utils,packageDescription)
importFrom(utils,read.delim)
importFrom(utils,read.table)
yulab.utils/NEWS.md 0000644 0001762 0000144 00000012627 15137764124 013645 0 ustar ligges users # yulab.utils 0.2.4
+ stabilize cache TTL unit test for r-devel checks (2026-02-02, Mon)
# yulab.utils 0.2.3
+ `download_yulab_file` (2025-12-15, Mon)
+ add unit test (2025-12-08, Mon)
+ Extend cache system with TTL, pruning, persistence and memoization (2025-12-08, Mon)
- `update_cache_item(item, elements, ttl=)` sets per-entry expiration
- `get_cache_element(item, elements, default=, prune_expired=)` supports default values and auto-pruning of expired entries
- `with_cache(item, key, compute, ttl=)` computes and caches results (returns cached value on hit)
- `prune_cache_item(item)` prunes expired entries; `rm_cache_entry(item, key)` removes a single entry
- `cache_list_items()` and `cache_size()` list items and estimate total cache size
- `cache_save(path)` and `cache_load(path)` serialize and restore the cache environment
+ update man (2025-12-08, Mon)
+ `load_OrgDb()` to load OrgDb object (2025-12-04, Thu)
- move from 'GOSemSim'
+ `parse_ratio` to parse ratio string, e.g., "1/2" (2025-12-04, Thu)
- move from 'DOSE'
+ set `check_pkg` as an alias of `check_packages` (2025-12-01, Mon)
# yulab.utils 0.2.2
+ add error handling functions (2025-12-01, Mon)
- `yulab_abort()`
- `yulab_warn()`
- `yulab_inform()`
+ check input validity with detailed error messages (2025-12-01, Mon)
- `check_input()`
- `check_package()`
- `check_file()`
- `check_range()`
- `check_directory()`
+ `quiet()` to suppress messages and output from `x` (2025-12-01, Mon)
+ add `subdir` parameter in `install_zip` and `install_zip_gh` (2025-09-09, Tue)
+ `where` return the full path of a command, "" if not found (2025-09-01, Mon)
- internally call `which` for OSX and Linux and `where` for Windows
# yulab.utils 0.2.1
+ export `user_dir()` (2025-08-16, Sat)
# yulab.utils 0.2.0
+ bug fixed in `get_caller_package()` (2025-01-08, Wed)
# yulab.utils 0.1.9
+ `c2()` to concate two vectors into a 'chunked_array' object (2024-12-03, Tue)
# yulab.utils 0.1.8
+ add new citation (The Innovation 2024) (2024-11-07, Thu)
+ `pload()` now supports github package (2024-11-06, Wed)
+ bug fixed in `pkg_ref()` (2024-08-26, Mon)
# yulab.utils 0.1.7
+ `has_internet()` for testing internet connection (2024-08-26, Mon)
+ `pkg_ref()` to access textVersion of package reference (2024-08-21, Wed)
+ export `str_detect()` (20024-08-19, Mon)
+ `user_dir()` to setup user data dir (20024-08-17, Sat)
+ `which_os()` to return the system name
+ `has_bin()` to check whether a command is exist in the system
# yulab.utils 0.1.6
+ `mydownload()` for downloading online file (2024-08-17, Sat)
- internally use 'httr2' and is 'https' friendly
+ update `bib_ggtree()` and `bib_knowledge()` with all previous related publications (2024-08-12, Mon)
+ remove memory caching and disable file cache by default in `yread()` and `yread_tsv()` (2024-07-27, Sat)
+ `bib_ggtree()` and `bib_knowledge()` (2024-07-27, Sat)
# yulab.utils 0.1.5
+ `yulab_msg()` for startup message of packages developed by YuLab (2024-07-26, Fri)
# yulab.utils 0.1.4
+ `str_extract()` to extract substring using a regular expression pattern (2024--01-25, Thu)
# yulab.utils 0.1.3
+ with cache ability (2023-12-27, Wed)
- `initial_cache()`
- `initial_cache_item()`
- `get_cache()`
- `get_cache_item()`
- `get_cache_element()`
- `rm_cache_item()`
- `rm_cache()`
# yulab.utils 0.1.2
+ mv translate functions to the 'fanyi' package (2023-12-14, Thu)
+ tools to switch from PCRE or TRE in regular expression (2023-12-13, Wed)
# yulab.utils 0.1.1
+ use `normalizePath()` in `o()` to convert file paths to canonical form (2023-10-06, Fri, #4)
+ change the default parameter, `ref = "master"` to `ref = "HEAD"` in the `install_zip_gh()` function to use the default branch of the GitHub repo (2023-10-02, Mon)
# yulab.utils 0.1.0
+ `install_zip()` allows both binary and source zip files (2023-09-20, Wed)
+ `pload()` for loading package with the ability to install it if not available (2023-09-16, Sat)
+ `get_dependencies()` and `packageTitle()` (2023-09-11, Mon)
+ import 'fs' and 'digest' (2023-09-07, Thu)
# yulab.utils 0.0.9
+ `ls2df()` convert list of vector to a data.frame (2023-09-01, Fri)
# yulab.utils 0.0.8
+ `mat2list()` and `combinations()` (2023-08-22, Tue)
+ remove default 'params' setting in `yread_tsv()` (2023-08-15, Tue)
# yulab.utils 0.0.7
+ update `check_pkg()` to call `rlang::check_installed()` with reason set automatically (2023-08-03, Thu)
+ `yread()` and `yread_tsv()` that read file with caching (2023-08-02, Wed)
+ `rbindlist()` to rbind a list (2023-08-01, Tue)
+ `exec()` to run system command (2023-06-19, Mon)
+ `scale_range()` to normalize data by range (2023-06-18, Sun)
# yulab.utils 0.0.6
+ `mat2df()` to convert matrix to a tidy data frame (2022-12-20, Tue)
+ `str_starts()` and `str_ends()` (2022-07-29, Fri)
# yulab.utils 0.0.5
+ `get_fun_from_pkg()` outputs friendly message if the pkg is not installed (2022-06-08, Wed)
+ `show_in_excel()`, `CRANpkg()`, `Biocpkg()`, `Githubpkg()`, `mypkg()` (2021-10-13, Wed)
# yulab.utils 0.0.4
+ `str_wrap()` (2021-10-09, Sat)
# yulab.utils 0.0.3
+ `read.cb()` (2021-08-17)
# yulab.utils 0.0.2
+ `o()`, `install_zip()`, `get_fun_from_pkg()`
# yulab.utils 0.0.1
+ `is.installed()`, `scihub_dl()`, `sudo_install()`
yulab.utils/inst/ 0000755 0001762 0000144 00000000000 14660651434 013513 5 ustar ligges users yulab.utils/inst/prototype/ 0000755 0001762 0000144 00000000000 14723463462 015562 5 ustar ligges users yulab.utils/inst/prototype/sra.r 0000644 0001762 0000144 00000000364 14712366206 016531 0 ustar ligges users get_runinfo <- function(sra_id) {
x <- rentrez::entrez_fetch(db='sra', rettype='runinfo', id = sra_id)
read.csv(textConnection(x))
}
id <- "SRX5137765"
d <- get_runinfo(id)
head(d,2)
sprintf("fastq-dump %s", d$Run[1:3])
yulab.utils/inst/prototype/GEO.r 0000644 0001762 0000144 00000001420 14712361503 016343 0 ustar ligges users
get_gse <- function(gseID) {
gsecat <- sub("\\d{3}$", "nnn", gseID)
gsesoft <- sprintf("%s_family.soft.gz", gseID)
url <- sprintf("https://ftp.ncbi.nlm.nih.gov/geo/series/%s/%s/soft/%s", gsecat, gseID, gsesoft)
yulab.utils:::mydownload(url, destfile = gsesoft)
GEOquery::getGEO(filename = gsesoft)
}
get_gsm <- function(gse, item = "supplementary_file_1") {
lapply(GEOquery::GSMList(gse), function(x) x@header[item])
}
download_gsm <- function(gsm) {
for (x in gsm) {
destfile <- sub(".*/([^/]+)$", "\\1", x)
yulab.utils:::mydownload(x, destfile = destfile)
}
}
gseID <- "GSE123904"
gse <- get_gse(gseID)
gsm <- get_gsm(gse)
get_gsm(gse, 'extract_protocol_ch1') |> head(2)
download_gsm(gsm)
yulab.utils/man/ 0000755 0001762 0000144 00000000000 15137764151 013312 5 ustar ligges users yulab.utils/man/check_packages.Rd 0000644 0001762 0000144 00000001455 15117727205 016516 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/error-utils.r
\name{check_packages}
\alias{check_packages}
\alias{check_pkg}
\title{Check if required packages are installed with informative errors}
\usage{
check_packages(packages, reason = "for this functionality")
check_pkg(packages, reason = "for this functionality")
}
\arguments{
\item{packages}{Character vector of package names}
\item{reason}{Reason why these packages are needed}
}
\value{
Invisible TRUE if all packages are available, throws error otherwise
}
\description{
Enhanced package checking with better error messages and validation
}
\seealso{
Other validate-utils:
\code{\link{check_directory}()},
\code{\link{check_file}()},
\code{\link{check_input}()},
\code{\link{check_range}()}
}
\concept{validate-utils}
yulab.utils/man/regexpr-style.Rd 0000644 0001762 0000144 00000002110 15117727206 016403 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/regexpr.R
\name{set_PCRE}
\alias{set_PCRE}
\alias{set_TRE}
\alias{use_perl}
\alias{set_regexpr_style}
\alias{auto_set_regexpr_style}
\title{Switch regular expression style (PCRE vs TRE)}
\usage{
set_PCRE()
set_TRE()
use_perl()
set_regexpr_style(style)
auto_set_regexpr_style()
}
\arguments{
\item{style}{one of 'PCRE' or 'TRE'}
}
\value{
Logical indicating whether to use \code{perl}
}
\description{
\itemize{
\item \code{set_regexpr_style()} selects the style explicitly.
\item \code{auto_set_regexpr_style()} chooses based on OS (TRE on Windows; PCRE elsewhere).
\item \code{set_PCRE()} and \code{set_TRE()} force the style.
}
}
\details{
These functions do not change the behavior of \code{gsub()}/\code{regexpr()} directly.
They set a global option that you can read via \code{use_perl()} and pass to \code{gsub()}/\code{regexpr()}.
}
\references{
https://stackoverflow.com/questions/47240375/regular-expressions-in-base-r-perl-true-vs-the-default-pcre-vs-tre
}
\author{
Guangchuang Yu
}
\concept{regex-utils}
yulab.utils/man/install_zip_gh.Rd 0000644 0001762 0000144 00000001367 15057724712 016616 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/install_zip.R
\name{install_zip_gh}
\alias{install_zip_gh}
\title{install_zip_gh}
\usage{
install_zip_gh(
repo,
ref = "HEAD",
subdir = NULL,
args = "--no-build-vignettes"
)
}
\arguments{
\item{repo}{github repo}
\item{ref}{github branch, default is HEAD, which means the default branch of the GitHub repo}
\item{subdir}{sub directory that contains R package files, default is NULL}
\item{args}{argument to build package}
}
\value{
No return value, called for installing github package
}
\description{
install github package
}
\details{
it download the zip file first and use \code{install_zip} to install it
}
\author{
Guangchuang Yu
}
yulab.utils/man/yulab_msg.Rd 0000644 0001762 0000144 00000000554 15115332234 015554 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/yulab-msg.R
\name{yulab_msg}
\alias{yulab_msg}
\title{yulab_msg}
\usage{
yulab_msg(pkgname = NULL, n = 1)
}
\arguments{
\item{pkgname}{Package name}
\item{n}{Number of citation messages}
}
\value{
Package message
}
\description{
Messages for YuLab packages
}
\author{
Guangchuang Yu
}
yulab.utils/man/str_wrap.Rd 0000644 0001762 0000144 00000001105 15115332234 015424 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/str-utils.R
\name{str_wrap}
\alias{str_wrap}
\title{str_wrap}
\usage{
str_wrap(string, width = getOption("width"))
}
\arguments{
\item{string}{Input string}
\item{width}{Maximum characters before wrapping}
}
\value{
Updated strings with \code{"\\n"} inserted
}
\description{
Wrap long strings to multiple lines
}
\seealso{
Other str-utils:
\code{\link{str_detect}()},
\code{\link{str_extract}()},
\code{\link{str_starts}()}
}
\author{
Guangchuang Yu
}
\concept{str-utils}
yulab.utils/man/yulab-cache.Rd 0000644 0001762 0000144 00000003540 15117727205 015755 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cache.R
\name{initial_cache}
\alias{initial_cache}
\alias{get_cache}
\alias{rm_cache}
\alias{initial_cache_item}
\alias{get_cache_item}
\alias{rm_cache_item}
\alias{update_cache_item}
\alias{get_cache_element}
\alias{prune_cache_item}
\alias{cache_list_items}
\alias{cache_size}
\alias{cache_save}
\alias{cache_load}
\alias{with_cache}
\title{Cache intermediate data}
\usage{
initial_cache()
get_cache()
rm_cache()
initial_cache_item(item)
get_cache_item(item)
rm_cache_item(item)
update_cache_item(item, elements, ttl = NULL)
get_cache_element(item, elements, default = NULL, prune_expired = TRUE)
prune_cache_item(item)
cache_list_items()
cache_size()
cache_save(path)
cache_load(path)
with_cache(item, key, compute, ttl = NULL)
}
\arguments{
\item{item}{Cache item name}
\item{elements}{Elements to cache}
\item{ttl}{Time-to-live in seconds}
\item{default}{Default value if cache element is missing}
\item{prune_expired}{Logical, whether to prune expired items}
\item{path}{File path to save or load cache}
\item{key}{Element key}
\item{compute}{Function to compute value when missing}
}
\value{
Cache environment, item, or selected elements
}
\description{
Utilities to cache intermediate data: initialize items, update items,
remove items, and retrieve elements.
}
\examples{
\dontrun{
slow_fib <- function(x) {
if (x < 2) return(1)
slow_fib(x-2) + slow_fib(x-1)
}
fast_fib <- function(x) {
if (x < 2) return(1)
res <- get_cache_element('fibonacci', as.character(x))
if (!is.null(res)) {
return(res)
}
res <- fast_fib(x-2) + fast_fib(x-1)
e <- list()
e[[as.character(x)]] <- res
update_cache_item('fibonacci', e)
return(res)
}
system.time(slow_fib(30))
system.time(fast_fib(30))
}
}
\concept{cache-utils}
yulab.utils/man/str-detect.Rd 0000644 0001762 0000144 00000001063 15115332234 015644 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/str-utils.R
\name{str_detect}
\alias{str_detect}
\title{str_detect}
\usage{
str_detect(string, pattern, negate = FALSE)
}
\arguments{
\item{string}{Input string}
\item{pattern}{Pattern to look for}
\item{negate}{If \code{TRUE}, invert the result}
}
\value{
Logical vector
}
\description{
Detect presence/absence of a match
}
\seealso{
Other str-utils:
\code{\link{str_extract}()},
\code{\link{str_starts}()},
\code{\link{str_wrap}()}
}
\author{
Guangchuang Yu
}
\concept{str-utils}
yulab.utils/man/scihub-dl.Rd 0000644 0001762 0000144 00000000726 14404503310 015440 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/scihub-dl.R
\name{scihub_dl}
\alias{scihub_dl}
\title{download publication via scihub}
\usage{
scihub_dl(doi, scihub = "sci-hub.tw", download = TRUE)
}
\arguments{
\item{doi}{doi}
\item{scihub}{scihub website}
\item{download}{whether download the pdf file}
}
\value{
pdf url
}
\description{
using scihub to download publication using doi
}
\author{
Guangchuang Yu
}
yulab.utils/man/read.cb.Rd 0000644 0001762 0000144 00000001062 15115332233 015062 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/file.R
\name{read.cb}
\alias{read.cb}
\title{read.cb}
\usage{
read.cb(reader = read.table, ...)
}
\arguments{
\item{reader}{function to read the clipboard}
\item{...}{parameters for the reader}
}
\value{
clipboard content, output type depends on the output of the reader
}
\description{
read clipboard
}
\seealso{
Other io-utils:
\code{\link{o}()},
\code{\link{show_in_excel}()},
\code{\link{yread_tsv}()}
}
\author{
Guangchuang Yu
}
\concept{io-utils}
yulab.utils/man/check_directory.Rd 0000644 0001762 0000144 00000001573 15117727205 016745 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/error-utils.r
\name{check_directory}
\alias{check_directory}
\title{Check if directory exists and is accessible}
\usage{
check_directory(
path,
create_if_missing = FALSE,
check_write_permission = TRUE,
arg_name = "directory"
)
}
\arguments{
\item{path}{Directory path}
\item{create_if_missing}{Whether to create directory if it doesn't exist}
\item{check_write_permission}{Whether to verify write permissions}
\item{arg_name}{Name of the argument for error messages}
}
\value{
Invisible TRUE if valid, throws error otherwise
}
\description{
Validates directory existence and accessibility with options to create if missing
}
\seealso{
Other validate-utils:
\code{\link{check_file}()},
\code{\link{check_input}()},
\code{\link{check_packages}()},
\code{\link{check_range}()}
}
\concept{validate-utils}
yulab.utils/man/install_zip.Rd 0000644 0001762 0000144 00000001102 15057724712 016123 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/install_zip.R
\name{install_zip}
\alias{install_zip}
\title{install_zip}
\usage{
install_zip(file, subdir = NULL, args = "--no-build-vignettes")
}
\arguments{
\item{file}{zip file}
\item{subdir}{sub directory that contains R package files, default is NULL}
\item{args}{argument to build package}
}
\value{
No return value, called for install R package from zip file of source codes
}
\description{
install R package from zip file of source codes
}
\author{
Guangchuang Yu
}
yulab.utils/man/o.Rd 0000644 0001762 0000144 00000001113 15115332233 014017 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/file.R
\name{o}
\alias{o}
\title{o}
\usage{
o(file = ".")
}
\arguments{
\item{file}{to be open; open working directory by default}
}
\value{
No return value, called for opening specific directory or file
}
\description{
open selected directory or file
}
\examples{
\dontrun{
## to open current working directory
o()
}
}
\seealso{
Other io-utils:
\code{\link{read.cb}()},
\code{\link{show_in_excel}()},
\code{\link{yread_tsv}()}
}
\author{
Guangchuang Yu
}
\concept{io-utils}
yulab.utils/man/check_file.Rd 0000644 0001762 0000144 00000001360 15117727205 015652 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/error-utils.r
\name{check_file}
\alias{check_file}
\title{Handle file operations with proper error messages}
\usage{
check_file(path, operation = "read", must_exist = TRUE)
}
\arguments{
\item{path}{File path}
\item{operation}{Operation being performed (read, write, etc.)}
\item{must_exist}{Whether the file must exist}
}
\value{
Invisible TRUE if operation can proceed, throws error otherwise
}
\description{
Enhanced file validation with comprehensive checks and better error messages
}
\seealso{
Other validate-utils:
\code{\link{check_directory}()},
\code{\link{check_input}()},
\code{\link{check_packages}()},
\code{\link{check_range}()}
}
\concept{validate-utils}
yulab.utils/man/combinations.Rd 0000644 0001762 0000144 00000000465 14471060707 016267 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/combinations.R
\name{combinations}
\alias{combinations}
\title{combinations}
\usage{
combinations(n)
}
\arguments{
\item{n}{number of sets}
}
\value{
a list of all combinations
}
\description{
all possible combinations of n sets
}
yulab.utils/man/yread.Rd 0000644 0001762 0000144 00000002017 15117727205 014702 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/file.R
\name{yread_tsv}
\alias{yread_tsv}
\alias{yread}
\title{yread}
\usage{
yread_tsv(
file,
reader = utils::read.delim,
params = list(),
cache_dir = tempdir()
)
yread(file, reader = readLines, params = list(), cache_dir = NULL)
}
\arguments{
\item{file}{a file or url}
\item{reader}{a function to read the 'file_url'}
\item{params}{a list of parameters that passed to the 'reader'}
\item{cache_dir}{a folder to store cache files. If set to NULL will disable cache.}
}
\value{
the output of using the 'reader' to read the 'file_url' with parameters specified by the 'params'
}
\description{
read file with caching
}
\details{
This function read a file (local or url) and cache the content.
}
\seealso{
Other io-utils:
\code{\link{o}()},
\code{\link{read.cb}()},
\code{\link{show_in_excel}()}
Other io-utils:
\code{\link{o}()},
\code{\link{read.cb}()},
\code{\link{show_in_excel}()}
}
\author{
Yonghe Xia and Guangchuang Yu
}
\concept{io-utils}
yulab.utils/man/download_yulab_file.Rd 0000644 0001762 0000144 00000001120 15117720071 017564 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/download.R
\name{download_yulab_file}
\alias{download_yulab_file}
\title{Process YuLab File Download}
\usage{
download_yulab_file(destfile, urls, gzfile = FALSE, appname = NULL)
}
\arguments{
\item{destfile}{character. Local file path.}
\item{urls}{character vector. Base URLs for download. Remote is is \code{urls/basename(destfile)}}
\item{gzfile}{logical. Whether the remote file is gzipped.}
\item{appname}{character. R package name.}
}
\description{
Process YuLab File Download
}
\author{
Guangchuang Yu
}
yulab.utils/man/mat2df.Rd 0000644 0001762 0000144 00000001100 14474263201 014737 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/matrix-utils.R
\name{mat2df}
\alias{mat2df}
\title{mat2df}
\usage{
mat2df(x)
}
\arguments{
\item{x}{the input matrix}
}
\value{
a data.frame in long format with the 'value' column stores the original values
and 'row' and 'col' columns stored in row and column index as in x
}
\description{
convert a matrix to a tidy data frame
(from wide to long format as described in the tidyverse concept)
}
\examples{
x <- matrix(1:15, nrow = 3)
mat2df(x)
}
\author{
Guangchuang Yu
}
yulab.utils/man/packageTitle.Rd 0000644 0001762 0000144 00000001141 15117727206 016171 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{packageTitle}
\alias{packageTitle}
\title{packageTitle}
\usage{
packageTitle(pkg, repo = "CRAN")
}
\arguments{
\item{pkg}{package name}
\item{repo}{'CRAN' and/or 'BioC'}
}
\value{
reverse dependencies
}
\description{
Extract package title
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{Githubpkg}()},
\code{\link{get_dependencies}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{is.installed}()},
\code{\link{mypkg}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/quiet.Rd 0000644 0001762 0000144 00000000420 15113172734 014716 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/quiet.r
\name{quiet}
\alias{quiet}
\title{quiet}
\usage{
quiet(x)
}
\arguments{
\item{x}{some code}
}
\value{
the result of \code{x}
}
\description{
Suppress messages and output from \code{x}
}
yulab.utils/man/has_internet.Rd 0000644 0001762 0000144 00000000727 15115332233 016256 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/os.R
\name{has_internet}
\alias{has_internet}
\title{has_internet}
\usage{
has_internet(site = "https://www.baidu.com/")
}
\arguments{
\item{site}{URL to test connection}
}
\value{
logical value
}
\description{
test for internect connection via reading lines from a URL
}
\seealso{
Other os-utils:
\code{\link{exec}()},
\code{\link{user_dir}()}
}
\author{
Guangchuang Yu
}
\concept{os-utils}
yulab.utils/man/c2.Rd 0000644 0001762 0000144 00000000617 14723464027 014110 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/concat.r
\name{c2}
\alias{c2}
\title{c2}
\usage{
c2(x, y)
}
\arguments{
\item{x}{a vector or chunked_array object}
\item{y}{a vector or chunked_array object}
}
\value{
chunked_array object
}
\description{
chunked array
}
\details{
concate two vector/chunked_array into a chunked_array object
}
\author{
Guangchuang Yu
}
yulab.utils/man/load_OrgDb.Rd 0000644 0001762 0000144 00000000516 15114322503 015561 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/load-orgdb.r
\name{load_OrgDb}
\alias{load_OrgDb}
\title{load_OrgDb}
\usage{
load_OrgDb(OrgDb)
}
\arguments{
\item{OrgDb}{OrgDb object or OrgDb name}
}
\value{
OrgDb object
}
\description{
load OrgDb
}
\author{
Guangchuang Yu \url{https://yulab-smu.top}
}
yulab.utils/man/check_range.Rd 0000644 0001762 0000144 00000001517 15117727205 016033 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/error-utils.r
\name{check_range}
\alias{check_range}
\title{Check if value is within specified range}
\usage{
check_range(x, min = NULL, max = NULL, inclusive = TRUE, arg_name = "value")
}
\arguments{
\item{x}{Numeric value to check}
\item{min}{Minimum allowed value (optional)}
\item{max}{Maximum allowed value (optional)}
\item{inclusive}{Whether bounds are inclusive (default: TRUE)}
\item{arg_name}{Name of the argument for error messages}
}
\value{
Invisible TRUE if valid, throws error otherwise
}
\description{
Validates that a numeric value falls within the specified range
}
\seealso{
Other validate-utils:
\code{\link{check_directory}()},
\code{\link{check_file}()},
\code{\link{check_input}()},
\code{\link{check_packages}()}
}
\concept{validate-utils}
yulab.utils/man/pload.Rd 0000644 0001762 0000144 00000001542 15117727205 014677 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{pload}
\alias{pload}
\title{pload}
\usage{
pload(package, action = "auto")
}
\arguments{
\item{package}{package name}
\item{action}{Installation function; \code{"auto"} tries \code{BiocManager::install()} if available}
}
\value{
the selected package loaded to the R session
}
\description{
Load a package
}
\details{
Uses \code{library()} to load \code{package}. If not installed, attempts installation
via \code{rlang::check_installed()} (optionally using \code{BiocManager::install()}).
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{Githubpkg}()},
\code{\link{get_dependencies}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{is.installed}()},
\code{\link{mypkg}()},
\code{\link{packageTitle}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/cran-bioc-pkg.Rd 0000644 0001762 0000144 00000001202 15117727206 016206 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{CRANpkg}
\alias{CRANpkg}
\alias{Biocpkg}
\title{Markdown link to CRAN/Bioconductor}
\usage{
CRANpkg(pkg)
Biocpkg(pkg)
}
\arguments{
\item{pkg}{package name}
}
\value{
md text string
}
\description{
Markdown link to CRAN/Bioconductor
}
\seealso{
Other pkg-utils:
\code{\link{Githubpkg}()},
\code{\link{get_dependencies}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{is.installed}()},
\code{\link{mypkg}()},
\code{\link{packageTitle}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/show_in_excel.Rd 0000644 0001762 0000144 00000000757 15115332233 016424 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/file.R
\name{show_in_excel}
\alias{show_in_excel}
\title{show_in_excel}
\usage{
show_in_excel(.data)
}
\arguments{
\item{.data}{a data frame to be open}
}
\value{
original .data
}
\description{
Open data frame in Excel. It can be used in pipe.
}
\seealso{
Other io-utils:
\code{\link{o}()},
\code{\link{read.cb}()},
\code{\link{yread_tsv}()}
}
\author{
Guangchuang Yu
}
\concept{io-utils}
yulab.utils/man/exec.Rd 0000644 0001762 0000144 00000000656 15115332233 014520 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/os.R
\name{exec}
\alias{exec}
\title{exec}
\usage{
exec(command)
}
\arguments{
\item{command}{system command to run}
}
\value{
An \code{exec} instance that stores system command outputs
}
\description{
run system command
}
\seealso{
Other os-utils:
\code{\link{has_internet}()},
\code{\link{user_dir}()}
}
\author{
Guangchuang Yu
}
\concept{os-utils}
yulab.utils/man/rbindlist.Rd 0000644 0001762 0000144 00000000500 15115332233 015552 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/list.R
\name{rbindlist}
\alias{rbindlist}
\title{rbindlist}
\usage{
rbindlist(x)
}
\arguments{
\item{x}{List with similar elements that can be row-bound}
}
\value{
\code{data.frame}
}
\description{
Row-bind a list
}
\author{
Guangchuang Yu
}
yulab.utils/man/parse_ratio.Rd 0000644 0001762 0000144 00000000557 15115332233 016104 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/parse_ratio.R
\name{parse_ratio}
\alias{parse_ratio}
\title{parse_ratio}
\usage{
parse_ratio(ratio)
}
\arguments{
\item{ratio}{Character vector of ratios}
}
\value{
Numeric vector
}
\description{
Parse character ratio to double, e.g., \code{1/5} → \code{0.2}
}
\author{
Guangchuang Yu
}
yulab.utils/man/get_dependencies.Rd 0000644 0001762 0000144 00000001173 15117727205 017065 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{get_dependencies}
\alias{get_dependencies}
\title{get_dependencies}
\usage{
get_dependencies(pkg, repo = c("CRAN", "BioC"))
}
\arguments{
\item{pkg}{package name}
\item{repo}{'CRAN' and/or 'BioC'}
}
\value{
reverse dependencies
}
\description{
Get reverse dependencies
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{Githubpkg}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{is.installed}()},
\code{\link{mypkg}()},
\code{\link{packageTitle}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/yulab-message.Rd 0000644 0001762 0000144 00000001242 15117727205 016333 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/error-utils.r
\name{yulab_abort}
\alias{yulab_abort}
\alias{yulab_warn}
\alias{yulab_inform}
\title{Standardized error handling}
\usage{
yulab_abort(message, class = "yulab_error", ...)
yulab_warn(message, class = "yulab_warning", ...)
yulab_inform(message, class = "yulab_info", ...)
}
\arguments{
\item{message}{Message string}
\item{class}{Custom class for categorization}
\item{...}{Additional context}
}
\value{
No return value
}
\description{
Provides \code{rlang}-based wrappers for messaging: \code{yulab_abort()}, \code{yulab_warn()},
and \code{yulab_inform()}.
}
\concept{messages}
yulab.utils/man/get_fun_from_pkg.Rd 0000644 0001762 0000144 00000001234 15117727206 017112 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{get_fun_from_pkg}
\alias{get_fun_from_pkg}
\title{get_fun_from_pkg}
\usage{
get_fun_from_pkg(pkg, fun)
}
\arguments{
\item{pkg}{package}
\item{fun}{function}
}
\value{
function
}
\description{
load function from package
}
\examples{
get_fun_from_pkg('utils', 'zip')
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{Githubpkg}()},
\code{\link{get_dependencies}()},
\code{\link{is.installed}()},
\code{\link{mypkg}()},
\code{\link{packageTitle}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/user_dir.Rd 0000644 0001762 0000144 00000001117 15115332233 015401 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/os.R
\name{user_dir}
\alias{user_dir}
\title{user_dir}
\usage{
user_dir(appname = NULL, appauthor = NULL, ...)
}
\arguments{
\item{appname}{App name}
\item{appauthor}{App author}
\item{...}{additional parameters}
}
\value{
a directory (created if not exists)
}
\description{
get the user dir to save app caches, logs and data (a wrapper function of \code{rappdirs::user_cache_dir()})
}
\seealso{
Other os-utils:
\code{\link{exec}()},
\code{\link{has_internet}()}
}
\author{
Guangchuang Yu
}
\concept{os-utils}
yulab.utils/man/str-starts-ends.Rd 0000644 0001762 0000144 00000001253 15115332234 016644 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/str-utils.R
\name{str_starts}
\alias{str_starts}
\alias{str_ends}
\title{str_starts}
\usage{
str_starts(string, pattern, negate = FALSE)
str_ends(string, pattern, negate = FALSE)
}
\arguments{
\item{string}{Input string}
\item{pattern}{Pattern to match}
\item{negate}{If \code{TRUE}, return non-matching elements}
}
\value{
a logical vector
}
\description{
Detect patterns at the beginning or end of strings
}
\seealso{
Other str-utils:
\code{\link{str_detect}()},
\code{\link{str_extract}()},
\code{\link{str_wrap}()}
}
\author{
Guangchuang Yu
}
\concept{str-utils}
yulab.utils/man/yulab.utils-package.Rd 0000644 0001762 0000144 00000001212 14660773203 017437 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/yulab-utils-package.R
\docType{package}
\name{yulab.utils-package}
\alias{yulab.utils}
\alias{yulab.utils-package}
\title{yulab.utils: Supporting Functions for Packages Maintained by 'YuLab-SMU'}
\description{
Miscellaneous functions commonly used by 'YuLab-SMU'.
}
\seealso{
Useful links:
\itemize{
\item \url{https://yulab-smu.top/}
\item Report bugs at \url{https://github.com/YuLab-SMU/yulab.utils/issues}
}
}
\author{
\strong{Maintainer}: Guangchuang Yu \email{guangchuangyu@gmail.com} (\href{https://orcid.org/0000-0002-6485-8781}{ORCID})
}
\keyword{internal}
yulab.utils/man/mypkg.Rd 0000644 0001762 0000144 00000001130 15117727206 014721 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{mypkg}
\alias{mypkg}
\title{mypkg}
\usage{
mypkg(pkg, url)
}
\arguments{
\item{pkg}{package name}
\item{url}{package url}
}
\value{
md text string
}
\description{
Markdown link to a package
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{Githubpkg}()},
\code{\link{get_dependencies}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{is.installed}()},
\code{\link{packageTitle}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/check_input.Rd 0000644 0001762 0000144 00000001702 15117727205 016072 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/error-utils.r
\name{check_input}
\alias{check_input}
\title{Validate input with type/length constraints}
\usage{
check_input(
x,
type = NULL,
length = NULL,
min_length = NULL,
max_length = NULL,
allow_null = FALSE,
arg_name = "input"
)
}
\arguments{
\item{x}{Object to check}
\item{type}{Expected type (e.g., \code{"numeric"}, \code{"character"}, or class name)}
\item{length}{Expected length}
\item{min_length}{Minimum length}
\item{max_length}{Maximum length}
\item{allow_null}{Whether \code{NULL} is allowed}
\item{arg_name}{Argument name for messages}
}
\value{
Invisible \code{TRUE} on success
}
\description{
Enhanced input validation supporting base types and class checks.
}
\seealso{
Other validate-utils:
\code{\link{check_directory}()},
\code{\link{check_file}()},
\code{\link{check_packages}()},
\code{\link{check_range}()}
}
\concept{validate-utils}
yulab.utils/man/scale_range.Rd 0000644 0001762 0000144 00000000465 14443622064 016044 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/scale.R
\name{scale_range}
\alias{scale_range}
\title{scale-range}
\usage{
scale_range(data)
}
\arguments{
\item{data}{the input data.}
}
\value{
normalized data
}
\description{
normalized data by range
}
\author{
Guangchuang Yu
}
yulab.utils/man/str-extract.Rd 0000644 0001762 0000144 00000000772 15115332234 016054 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/str-utils.R
\name{str_extract}
\alias{str_extract}
\title{str_extract}
\usage{
str_extract(string, pattern)
}
\arguments{
\item{string}{Input string}
\item{pattern}{Regular expression to extract}
}
\value{
Substring
}
\description{
Extract a substring using a pattern
}
\seealso{
Other str-utils:
\code{\link{str_detect}()},
\code{\link{str_starts}()},
\code{\link{str_wrap}()}
}
\author{
Guangchuang Yu
}
\concept{str-utils}
yulab.utils/man/ls2df.Rd 0000644 0001762 0000144 00000000531 15115332233 014576 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/list.R
\name{ls2df}
\alias{ls2df}
\title{Convert a list of vectors (e.g., gene IDs) to \code{data.frame}}
\usage{
ls2df(inputList)
}
\arguments{
\item{inputList}{List of vectors}
}
\value{
\code{data.frame}
}
\description{
Convert a list of vectors to a data.frame
}
yulab.utils/man/mat2list.Rd 0000644 0001762 0000144 00000000554 14474263201 015335 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/matrix-utils.R
\name{mat2list}
\alias{mat2list}
\title{mat2list}
\usage{
mat2list(x)
}
\arguments{
\item{x}{the input matrix}
}
\value{
a list that contains matrix columns as its elements
}
\description{
convert a matrix to a list
}
\examples{
x <- matrix(1:15, nrow = 3)
mat2list(x)
}
yulab.utils/man/github-pkg.Rd 0000644 0001762 0000144 00000001120 15117727206 015632 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{Githubpkg}
\alias{Githubpkg}
\title{Markdown link to GitHub}
\usage{
Githubpkg(user, pkg)
}
\arguments{
\item{user}{github user}
\item{pkg}{package name}
}
\value{
md text string
}
\description{
Markdown link to GitHub
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{get_dependencies}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{is.installed}()},
\code{\link{mypkg}()},
\code{\link{packageTitle}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/man/is.installed.Rd 0000644 0001762 0000144 00000001226 15117727206 016171 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pkg-utils.R
\name{is.installed}
\alias{is.installed}
\title{is.installed}
\usage{
is.installed(packages)
}
\arguments{
\item{packages}{package names}
}
\value{
logical vector
}
\description{
Check whether packages are installed
}
\examples{
is.installed(c("dplyr", "ggplot2"))
}
\seealso{
Other pkg-utils:
\code{\link{CRANpkg}()},
\code{\link{Githubpkg}()},
\code{\link{get_dependencies}()},
\code{\link{get_fun_from_pkg}()},
\code{\link{mypkg}()},
\code{\link{packageTitle}()},
\code{\link{pload}()}
}
\author{
Guangchuang Yu
}
\concept{pkg-utils}
yulab.utils/DESCRIPTION 0000644 0001762 0000144 00000001627 15140042152 014233 0 ustar ligges users Package: yulab.utils
Title: Supporting Functions for Packages Maintained by 'YuLab-SMU'
Version: 0.2.4
Authors@R: c(person("Guangchuang", "Yu", email = "guangchuangyu@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-6485-8781")))
Description: Miscellaneous functions commonly used by 'YuLab-SMU'.
Depends: R (>= 4.2.0)
Imports: cli, digest, fs, methods, rappdirs, rlang, tools, utils
Suggests: httr2, jsonlite, openssl, R.utils, testthat (>= 3.0.0)
ByteCompile: true
License: Artistic-2.0
URL: https://yulab-smu.top/
BugReports: https://github.com/YuLab-SMU/yulab.utils/issues
Encoding: UTF-8
RoxygenNote: 7.3.3
Config/testthat/edition: 3
NeedsCompilation: no
Packaged: 2026-02-01 23:57:30 UTC; HUAWEI
Author: Guangchuang Yu [aut, cre] (ORCID:
)
Maintainer: Guangchuang Yu
Repository: CRAN
Date/Publication: 2026-02-02 06:30:02 UTC