Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: pm
Title: Project and Analysis Manager
Version: 0.1.10
Version: 0.1.11
Authors@R:
person("Alon", "Alexander", , "alon008@gmail.com", role = c("aut", "cre"))
Description: Enforces and supports a standardized folder structure for research
Expand Down
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# pm 0.1.11

## New Features

- Support subfolders in `PMAnalysis$get_output_path`
- Support subfolders in `PMAnalysis$list_outputs`
- Support subfolders in `get_artifact` (both `PMAnalysis` and `PmProject`)

# pm 0.1.10

## New Features
Expand Down
27 changes: 13 additions & 14 deletions R/analysis.R
Original file line number Diff line number Diff line change
Expand Up @@ -241,31 +241,23 @@ PMAnalysis <- R6Class("PMAnalysis",
}

# Get all files in the directory
files <- list.files(outputs_dir, full.names = TRUE)
files <- list.files(outputs_dir, full.names = FALSE, recursive = TRUE)
if (length(files) == 0) {
return(list())
}

# Filter to only files (not directories) using vectorized approach
file_info <- file.info(files)
is_file <- !is.na(file_info$isdir) & !file_info$isdir
files_only <- files[is_file]

if (length(files_only) == 0) {
return(list())
}

# Create PMData objects using lapply
file_ids <- tools::file_path_sans_ext(basename(files_only))
file_paths <- normalizePath(files_only, mustWork = FALSE)
file_ids <- gsub("\\", "/", tools::file_path_sans_ext(files), fixed = TRUE)
file_paths <- normalizePath(file.path(outputs_dir, files), mustWork = FALSE)

lapply(seq_along(files_only), function(i) {
lapply(seq_along(files), function(i) {
PMData$new(id = file_ids[i], path = file_paths[i])
})
},

#' @description
#' Get output path for a file, returning a PMData object.
#' Supports also subfolders using both unix-style and windows-style delimeteres ("/" and "\\").
#'
#' @param name Character. Name of the output file (with or without extension).
#' @param type Character. Optional type of output (table, object, image, figure, parquet, csv).
Expand All @@ -291,6 +283,11 @@ PMAnalysis <- R6Class("PMAnalysis",
#' intermediate <- analysis$get_output_path("temp_data", type = "table", intermediate = TRUE)
#' intermediate$id # "temp_data"
#' intermediate$path # full path to temp_data.parquet in intermediate/
#'
#' # Get output path with nested folders
#' output2 <- analysis$get_output_path("unique\\complex\\structure.rds")
#' output2$id # "unique/complex/structure"
#' output2$path
get_output_path = function(name, type = NULL, intermediate = FALSE) {
# Store original name for ID (without extension)
original_name <- name
Expand Down Expand Up @@ -332,7 +329,9 @@ PMAnalysis <- R6Class("PMAnalysis",

folder <- if (intermediate) constants$ANALYSIS_INTERMEDIATE_DIR else constants$ANALYSIS_OUTPUT_DIR

full_path <- normalizePath(file.path(self$path, folder, name), mustWork = FALSE)
name <- strsplit(name, "\\\\|/")
full_path_raw <- do.call(file.path, as.list(c(self$path, folder, unlist(name))))
full_path <- normalizePath(full_path_raw, mustWork = FALSE)

PMData$new(id = id, path = full_path)
},
Expand Down
7 changes: 5 additions & 2 deletions R/data.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ PMData <- R6Class("PMData",
chk::chk_scalar(path)
chk::chk_character(path)
self$id <- id
self$path <- path
self$path <- normalizePath(path, mustWork = FALSE)
},

#' @description
Expand Down Expand Up @@ -101,6 +101,9 @@ PMData <- R6Class("PMData",
#' data_rdata$write(obj1, obj2, obj3 = 42)
#' })
write = function(x, ...) {
# Create the folder in case it doesn't exist
dir.create(dirname(self$path), showWarnings = FALSE, recursive = TRUE)

# For RData files, we need to preserve object names from the original call
ext <- tolower(tools::file_ext(self$path))
if (ext %in% c("rdata", "rda")) {
Expand Down Expand Up @@ -129,7 +132,7 @@ PMData <- R6Class("PMData",
obj_names <- c(obj_names, obj_name)
}
}

# Call pm_write_file with explicit object names
pm_write_file(self$path, x, ..., object_names = obj_names)
} else {
Expand Down
1 change: 0 additions & 1 deletion R/data_utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -744,4 +744,3 @@ pm_write_file <- function(file, x, ..., object_names = NULL) {

invisible(file)
}

4 changes: 4 additions & 0 deletions R/project.R
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ PMProject <- R6Class("PMProject",
chk::chk_scalar(id)
chk::chk_character(id)

# Normalize (subfolder) id
prev_id = id
id <- gsub("\\", "/", id, fixed = TRUE)

# Determine which analyses to search
if (!is.null(analysis_name)) {
chk::chk_scalar(analysis_name)
Expand Down
2 changes: 1 addition & 1 deletion docs/404.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/LICENSE.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions docs/articles/file-formats.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/articles/file-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ head(tsv_data)
# Read the RDS object (automatically detects RDS format)
model <- analysis$get_artifact("model")$read()
str(model, max.level = 2)
#> <environment: 0x1228fe2e8>
#> <environment: 0x10d6cec18>

# Read RData (returns an environment)
rdata_env <- analysis$get_artifact("model_rdata")$read()
Expand Down
26 changes: 13 additions & 13 deletions docs/articles/getting-started.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading