getDataCM(), getProjectProgress() and getProjectsCM() no longer
fail with "lexical error: invalid char in json text" while 'ClimMob' is
still building a project's data export. They wait and try again, up to
getOption("ClimMobTools.tries", 10) times with
getOption("ClimMobTools.wait", 30) seconds between requests. Other
non-JSON responses, such as an invalid API key, now give a clear error.breadwheat project on the climmob3 server.This release introduces a new trial design algorithm, removes four
dependencies and fixes a bug that stopped the development version from
installing. Designs from randomise() differ from earlier versions for the
same seed.
randomise() and randomize() use a new design algorithm by Jacob van
Etten. The design is sequentially balanced: every prefix stays close to
balanced, so it remains good when only the first packages are distributed
or returned. Blocks are chosen by replication schedule, then by the exact
A-optimality gain, with availability as a hard limit. New arguments
ridge, polish and schedule. Arguments of the previous algorithm,
such as comp, are ignored with a warning.getSurvey() retrieves the survey questions of a 'ClimMob' project in a
given language.rmGeoIdentity() no longer prints the seed it uses. The random
displacement does not depend on the original coordinates, so anyone who
knows the seed can recover the exact locations. Leave seed = NULL for
data that will be shared. A given seed no longer changes the caller's
random number stream. The function now calls 'sf' by namespace, so 'sf'
no longer needs to be attached.CLIMMOB_KEY
instead of a key written in the test files, and are skipped when it is
not set.getDataCM() and getProjectProgress() build the request body with
'jsonlite', so quotes in project codes or user names no longer break the
request, and stop with a clear message when the server returns an error
status instead of failing while parsing the response.R/getSurvey.R that ran when the
package was loaded.Corrected typos and unclear wording in the help pages and the vignette.
Tests now run under R CMD check (they were excluded in .Rbuildignore).
Outdated tests for removed functions and arguments were replaced by tests
of the randomise() design: distinct items per package, equal item
counts, balance across positions, a connected comparison network,
availability limits, balanced prefixes, proportions and reproducibility.
Added tests for rmGeoIdentity().
Added an R CMD check workflow for Linux, macOS and Windows, and
AGENTS.md, a guide for AI agents working on the package.
Housekeeping improvements
Fixes an error in exportMeasuredTraits() that occurred when no measured trait
variables (ending in "_a", "_b", or "_c") were present in the dataset. The
function now returns a valid empty CM_df object instead of failing during the
binding step.
Added a suite of data-export functions to simplify extraction of structured ClimMob project outputs:
exportBlockData()exportMeasuredTraits()exportTrialMetadata()exportTricotRanks()exportVariablesDescription()These functions provide direct access to commonly used data structures in ClimMob projects, improving workflow efficiency for analysis and reporting.
as.data.frame.CM_list() method now defaults to pivot.wider = TRUE, returning a wide-format data frame.as.data.frame.CM_list() method has a validation line to only coerce to data.frame objects with more than 1 data point.as.data.frame.CM_list() method, improving code clarity and reusability
.replace_multichoice_codes().handle_geolocation_columns().replace_rankings().decode_assessments().merge_package_info().clean_column_names().drop_odk_system_fields().reorder_columns().safe_extract()as.data.frame.CM_list() tidynames = TRUE, producing more consistent and informative names..set_long() when pivot.wider = TRUE.project, package, registration, and assessments)._longitude, _latitude) would lead to the final data frame having zero columns. These are now removed conditionally and safely.getProjectsCM() adds a new variable in the output project_code that will represent the previous project_id. The new variable project_id will represent the id from the ClimMob server database not the id from the user list of projects.ClimMobTools:::as.data.frame().smart.round() to handle NA in the randomize() functionrandomize() to allocate blocksgetTraitList()getProjectsCM() to adapt to the new version of ClimMobuserowner = to getDataCM() to specify the owner of a given ClimMob projectgetProjectsCM()randomise() to check for unbalanced designsrandomise() deals with unbalanced proportions of technologies, meaning that we can test a whole set of technologies even when not all have equal availabilityrmGeoIdentity() is added to offer an approach to remove geographical identity of participantsrankTricot() builds a PlackettLuce rankings using the tricot datagetProjectProgress() returns the progress in a given projectas.data.frame() now handles ClimMob data without the assessment info.as.data.frame() decodes values from categorical variablesas.data.frame() decodes ties in the ranking datahttr::RETRY() instead of httr::GET() as suggested by Anna Vasylytsyaprint() method is addedservergetDataCM(), getProjectCM(), randomise() and seed_need()as.data.frame() is provided to coerce CM_list into a data frametemperature and rainfall now deals with one single lonlat pointbuild_rankings to work with the new implementations of PlackettLuce v0.2-8build_rankings