From a92d9c8637c01859e99bfabfe3104600c558bba1 Mon Sep 17 00:00:00 2001 From: George Chen <72078254+jiajic@users.noreply.github.com> Date: Sat, 13 Jul 2024 23:21:20 -0400 Subject: [PATCH 1/3] feat: `dir_manifest()` --- NAMESPACE | 1 + NEWS.md | 7 +++++- R/file_read.R | 46 +++++++++++++++++++++++++++++++++++++++ man/dir_manifest.Rd | 53 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 man/dir_manifest.Rd diff --git a/NAMESPACE b/NAMESPACE index 758f196..eec7cce 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -26,6 +26,7 @@ export(deprecate_warn) export(deprecated) export(depth) export(determine_cores) +export(dir_manifest) export(dt_dcast_string) export(dt_remove_na) export(dt_set_row_order) diff --git a/NEWS.md b/NEWS.md index aa35ae0..8e4ccf1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,10 @@ -# GiottoUtils 0.1.9 +# GiottoUtils 0.1.10 + +## New +- `dir_manifest()` for creating a named `list` of files within a directory. Mostly wraps `list.files()` + +# GiottoUtils 0.1.9 (2024/07/12) ## New - `deprecate_param()` utility function for streamlining code diff --git a/R/file_read.R b/R/file_read.R index 950c847..9eb5e2d 100644 --- a/R/file_read.R +++ b/R/file_read.R @@ -14,6 +14,52 @@ file_extension <- function(file) { } +#' @title Generate file manifest list from a directory +#' @name dir_manifest +#' @description Create a `list` of full filepaths (character) that are named +#' by with the respective `[basename()]`. Allows easy `$` exploration and +#' indexing of items.\cr +#' All params are directly passed to `[list.files()]` except +#' for `full.names`. `[list.files()]` also normally returns both actual files +#' and directories when `recursive = FALSE`, but this function specifically +#' tests if items are existing files and not directories with +#' `utils::file_test(op = -f)` and fully obeys that flag in all cases. +#' @param path a character vector of full path names; the default corresponds +#' to the working directory, `[getwd()]`. Tilde expansion (see [path.expand]) +#' and [`normalizePath()`] are performed. Missing values will be ignored. +#' Elements with a marked encoding will be converted to the native encoding +#' (and if that fails, considered non-existent). +#' @param pattern an optional regular expression. Only file names which match +#' the regular expression will be returned. +#' @param all.files a logical value. If `FALSE`, only the names of visible +#' files are returned (following Unix-style visibility, that is files whose +#' name does not start with a dot). If `TRUE`, all file names will be returned. +#' @param recursive logical. Should the listing recurse into directories? +#' @param ignore.case logical. Should pattern-matching be case-insensitive? +#' @param include.dirs logical. Should subdirectory names be included in +#' recursive listings? +#' @param no.. logical. Should both `"."` and `".."` be excluded also from +#' non-recursive listings? +#' @examples +#' dir_manifest() +#' @export +dir_manifest <- function( + path = ".", pattern = NULL, all.files = FALSE, recursive = FALSE, + ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE +) { + a <- get_args_list() + a$full.names = TRUE + fullpaths <- do.call("list.files", args = a) + fullpaths <- normalizePath(fullpaths) + if (include.dirs == FALSE) { + is_file <- utils::file_test(op = "-f", x = fullpaths) + fullpaths <- fullpaths[is_file] + } + names(fullpaths) <- basename(fullpaths) + return(as.list(fullpaths)) +} + + #' @title Fread specific rows based on column matches #' @name fread_colmatch #' @param file path to file to load diff --git a/man/dir_manifest.Rd b/man/dir_manifest.Rd new file mode 100644 index 0000000..f1b22b8 --- /dev/null +++ b/man/dir_manifest.Rd @@ -0,0 +1,53 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/file_read.R +\name{dir_manifest} +\alias{dir_manifest} +\title{Generate file manifest list from a directory} +\usage{ +dir_manifest( + path = ".", + pattern = NULL, + all.files = FALSE, + recursive = FALSE, + ignore.case = FALSE, + include.dirs = FALSE, + no.. = FALSE +) +} +\arguments{ +\item{path}{a character vector of full path names; the default corresponds +to the working directory, \verb{[getwd()]}. Tilde expansion (see \link{path.expand}) +and \code{\link[=normalizePath]{normalizePath()}} are performed. Missing values will be ignored. +Elements with a marked encoding will be converted to the native encoding +(and if that fails, considered non-existent).} + +\item{pattern}{an optional regular expression. Only file names which match +the regular expression will be returned.} + +\item{all.files}{a logical value. If \code{FALSE}, only the names of visible +files are returned (following Unix-style visibility, that is files whose +name does not start with a dot). If \code{TRUE}, all file names will be returned.} + +\item{recursive}{logical. Should the listing recurse into directories?} + +\item{ignore.case}{logical. Should pattern-matching be case-insensitive?} + +\item{include.dirs}{logical. Should subdirectory names be included in +recursive listings?} + +\item{no..}{logical. Should both \code{"."} and \code{".."} be excluded also from +non-recursive listings?} +} +\description{ +Create a \code{list} of full filepaths (character) that are named +by with the respective \verb{[basename()]}. Allows easy \code{$} exploration and +indexing of items.\cr +All params are directly passed to \verb{[list.files()]} except +for \code{full.names}. \verb{[list.files()]} also normally returns both actual files +and directories when \code{recursive = FALSE}, but this function specifically +tests if items are existing files and not directories with +\code{utils::file_test(op = -f)} and fully obeys that flag in all cases. +} +\examples{ +dir_manifest() +} From 87896da947363903c98c8034eced75cb45e642d8 Mon Sep 17 00:00:00 2001 From: George Chen <72078254+jiajic@users.noreply.github.com> Date: Sat, 13 Jul 2024 23:22:09 -0400 Subject: [PATCH 2/3] chore: bump version for dev --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3b96270..f9872b6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: GiottoUtils Title: Giotto Suite Utilities -Version: 0.1.9 +Version: 0.1.10 Authors@R: c( person("Ruben", "Dries", email = "rubendries@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-7650-7754")), From 39258c0cbcba61a520b89b12dbb86ef0971bc9ee Mon Sep 17 00:00:00 2001 From: George Chen <72078254+jiajic@users.noreply.github.com> Date: Sun, 14 Jul 2024 22:51:58 -0400 Subject: [PATCH 3/3] enh: `dir_manifest()` return as list is now optional --- R/file_read.R | 14 +++++++++++--- man/dir_manifest.Rd | 9 ++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/R/file_read.R b/R/file_read.R index 9eb5e2d..2c63eda 100644 --- a/R/file_read.R +++ b/R/file_read.R @@ -40,14 +40,21 @@ file_extension <- function(file) { #' recursive listings? #' @param no.. logical. Should both `"."` and `".."` be excluded also from #' non-recursive listings? +#' @param as.list logical. Should output be a list or a named character vector #' @examples #' dir_manifest() +#' @returns full and normalized filepaths named by the file basename as either +#' a list (default) or if `as.list = FALSE`, a character vector. #' @export dir_manifest <- function( path = ".", pattern = NULL, all.files = FALSE, recursive = FALSE, - ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE + ignore.case = FALSE, include.dirs = FALSE, no.. = FALSE, + as.list = TRUE ) { - a <- get_args_list() + a <- get_args_list(keep = c( + "path", "pattern", "all.files", "recursive", "ignore.case", + "include.dirs", "no.." + )) a$full.names = TRUE fullpaths <- do.call("list.files", args = a) fullpaths <- normalizePath(fullpaths) @@ -56,7 +63,8 @@ dir_manifest <- function( fullpaths <- fullpaths[is_file] } names(fullpaths) <- basename(fullpaths) - return(as.list(fullpaths)) + if (as.list) fullpaths <- as.list(fullpaths) + return(fullpaths) } diff --git a/man/dir_manifest.Rd b/man/dir_manifest.Rd index f1b22b8..1b75a17 100644 --- a/man/dir_manifest.Rd +++ b/man/dir_manifest.Rd @@ -11,7 +11,8 @@ dir_manifest( recursive = FALSE, ignore.case = FALSE, include.dirs = FALSE, - no.. = FALSE + no.. = FALSE, + as.list = TRUE ) } \arguments{ @@ -37,6 +38,12 @@ recursive listings?} \item{no..}{logical. Should both \code{"."} and \code{".."} be excluded also from non-recursive listings?} + +\item{as.list}{logical. Should output be a list or a named character vector} +} +\value{ +full and normalized filepaths named by the file basename as either +a list (default) or if \code{as.list = FALSE}, a character vector. } \description{ Create a \code{list} of full filepaths (character) that are named