Skip to content
Open
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
33 changes: 33 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,36 @@ After `runAnalysis()`, check:
- Use `createJaspTable()`, `createJaspPlot()`, `createJaspHtml()` for output elements
- Always set `$dependOn()` for proper caching and state management
- Use containers for grouping related elements, state objects for reusing computed results

## Container Environment (overrides Session Setup section above)

This is a **headless Docker container**. There is no interactive user.

### MANDATORY FIRST ACTION — R Session Connection

Before doing ANYTHING else (before reading code, before exploring the repo),
you MUST connect to the pre-started R session:

1. Call `list_r_sessions` to discover available sessions.
2. Call `select_r_session` to connect to the listed session.
3. Only then proceed with the workflow.

If `list_r_sessions` returns empty, the background R session failed to start.
Fall back to Bash for R execution. Do NOT spend more than 2 turns debugging.

This step is NOT optional. Without it, `btw_tool_run_r` will fail.

### Other container rules

- `session_startup.R` is NOT relevant here — ignore references to it.
- Do NOT run any git commands (the outer orchestrator handles git).

## Compact Instructions

When context is compacted, preserve:
- Current workflow stage (from /workspace/.openclaw-run/current_stage)
- Implementation plan (from /workspace/.openclaw-run/PLAN.md)
- The module name and original task description
- What git changes have been made so far

After compaction, re-read /workspace/.openclaw-run/RECOVERY.md to re-orient.
43 changes: 41 additions & 2 deletions R/TimeWeightedCharts.R
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,21 @@ timeWeightedCharts <- function(jaspResults, dataset, options) {
columnsToPass <- c(measurements, stages)
columnsToPass <- columnsToPass[columnsToPass != ""]
phase2 <- (options[["cumulativeSumChartSdSource"]] == "historical")
movingRangeLength <- options[["cumulativeSumChartAverageMovingRangeLength"]]
if (!phase2 && .stageHasTooFewObservationsForMovingRange(dataset, stages, movingRangeLength)) {
plot$setError(.timeWeightedStagesMovingRangeErrorMessage(
chartTitle = gettext("Cumulative sum chart"),
dataset = dataset,
stages = stages,
movingRangeLength = movingRangeLength
))
return(list("plot" = plot))
}

cusumChart <- .controlChart(dataset[columnsToPass], plotType = "cusum", stages = stages, xBarSdType = options[["cumulativeSumChartSdMethod"]],
nSigmasControlLimits = options[["cumulativeSumChartNumberSd"]], xAxisLabels = axisLabels,
cusumShiftSize = options[["cumulativeSumChartShiftSize"]], cusumTarget = options[["cumulativeSumChartTarget"]],
movingRangeLength = options[["cumulativeSumChartAverageMovingRangeLength"]], phase2 = phase2,
movingRangeLength = movingRangeLength, phase2 = phase2,
phase2Sd = options[["cumulativeSumChartSdValue"]], tableLabels = axisLabels, ruleList = ruleList)
table <- cusumChart$table
plot$plotObject <- cusumChart$plotObject
Expand All @@ -221,9 +232,20 @@ timeWeightedCharts <- function(jaspResults, dataset, options) {
columnsToPass <- c(measurements, stages)
columnsToPass <- columnsToPass[columnsToPass != ""]
phase2 <- (options[["exponentiallyWeightedMovingAverageChartSdSource"]] == "historical")
movingRangeLength <- options[["exponentiallyWeightedMovingAverageChartMovingRangeLength"]]
if (!phase2 && .stageHasTooFewObservationsForMovingRange(dataset, stages, movingRangeLength)) {
plot$setError(.timeWeightedStagesMovingRangeErrorMessage(
chartTitle = gettext("Exponentially weighted moving average chart"),
dataset = dataset,
stages = stages,
movingRangeLength = movingRangeLength
))
return(list("plot" = plot))
}

ewmaChart <- .controlChart(dataset[columnsToPass], plotType = "ewma", stages = stages, xBarSdType = options[["exponentiallyWeightedMovingAverageChartSdMethod"]],
nSigmasControlLimits = options[["exponentiallyWeightedMovingAverageChartSigmaControlLimits"]],
xAxisLabels = axisLabels, movingRangeLength = options[["exponentiallyWeightedMovingAverageChartMovingRangeLength"]],
xAxisLabels = axisLabels, movingRangeLength = movingRangeLength,
ewmaLambda = options[["exponentiallyWeightedMovingAverageChartLambda"]], phase2 = phase2,
phase2Sd = options[["exponentiallyWeightedMovingAverageChartSdValue"]], tableLabels = axisLabels,
ruleList = ruleList)
Expand All @@ -247,3 +269,20 @@ timeWeightedCharts <- function(jaspResults, dataset, options) {
return(ruleList)
}

.stageHasTooFewObservationsForMovingRange <- function(dataset, stages, movingRangeLength) {
if (identical(stages, "") || !stages %in% colnames(dataset))
return(FALSE)

stageCounts <- table(dataset[[stages]])
any(stageCounts < movingRangeLength)
}

.timeWeightedStagesMovingRangeErrorMessage <- function(chartTitle, dataset, stages, movingRangeLength) {
stageCounts <- table(dataset[[stages]])
minObservations <- min(stageCounts)
gettextf(paste0(
"At least one stage contains only %1$s observation(s). %2$s requires at least %3$s observations per stage ",
"for the selected moving range length. This can happen when too many stages are defined (for example one point ",
"per stage). Reduce the number of stages or lower the moving range length."
), minObservations, chartTitle, movingRangeLength)
}
Loading
Loading