R Under development (unstable) (2026-08-25 r90448 ucrt) -- "Unsuffered Consequences" Copyright (C) 2026 The R Foundation for Statistical Computing Platform: x86_64-w64-mingw32/x64 R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(agriME) > > # Core accounting identities and formula definitions. > m <- marketing_metrics( + producer_price = 1900, + consumer_price = 3150, + marketing_cost = 510, + marketing_margin = 740, + channel = "Channel A" + ) > stopifnot( + identical(m$channel, "Channel A"), + isTRUE(all.equal(m$price_spread, 1250)), + isTRUE(all.equal(m$price_spread_percent, 100 * 1250 / 3150)), + isTRUE(all.equal(m$producer_share_percent, 100 * 1900 / 3150)), + isTRUE(all.equal(m$acharya_efficiency, 1900 / 1250)), + isTRUE(all.equal(m$shepherd_efficiency, 3150 / 510)), + isTRUE(all.equal(m$conventional_efficiency, 1250 / 510)), + isTRUE(all.equal(m$accounting_gap, 0)) + ) > stopifnot( + isTRUE(all.equal(price_spread(1900, 3150), 1250)), + isTRUE(all.equal(price_spread(1900, 3150, TRUE), 100 * 1250 / 3150)), + isTRUE(all.equal(producers_share(1900, 3150), 100 * 1900 / 3150)), + isTRUE(all.equal( + marketing_efficiency(1900, 3150, 510, 740, "acharya"), + 1900 / 1250 + )), + isTRUE(all.equal( + marketing_efficiency(1900, 3150, 510, 740, "shepherd", "net_ratio"), + 3150 / 510 - 1 + )) + ) > > margin <- marketing_margin(2050, 2450, 140, 3150) > stopifnot( + margin$gross_margin == 400, + margin$net_margin == 260, + isTRUE(all.equal(margin$net_margin_share_percent, 100 * 260 / 3150)) + ) > > # Stage-level analysis and diagnostics. > data(tomato_channels) > channel_data <- as_market_channel(tomato_channels) > stopifnot(inherits(channel_data, "market_channel")) > stopifnot(nrow(validate_market_channel(channel_data)) == 0L) > > fit <- analyse_channels(channel_data) > stopifnot(inherits(fit, "agriME_analysis")) > stopifnot(nrow(fit$summary) == 4L, nrow(fit$actors) == 10L) > stopifnot(all(abs(fit$summary$accounting_gap) < 1e-10)) > direct <- fit$summary[fit$summary$channel == "Direct", ] > stopifnot( + direct$producer_price == 2420, + direct$consumer_price == 2600, + direct$price_spread == 180 + ) > > broken <- tomato_channels > broken$purchase_price[broken$channel == "Producer-Retailer" & + broken$stage == 2] <- 2200 > diagnostics <- validate_market_channel(as_market_channel(broken)) > stopifnot(any(diagnostics$code == "broken_price_link")) > > rupee <- consumer_rupee(fit) > rupee_sum <- tapply(rupee$percent, rupee$channel, sum) > stopifnot(all(abs(rupee_sum - 100) < 1e-10)) > > # Ranking, uncertainty, sensitivity, targets, and loss adjustment. > ranking <- rank_channels(fit) > stopifnot(inherits(ranking, "agriME_ranking")) > stopifnot(ranking$channel[ranking$rank == 1] == "Direct") > stopifnot(abs(sum(attr(ranking, "weights")) - 1) < 1e-12) > > data(market_observations) > set.seed(77) > old_seed <- .Random.seed > boot <- bootstrap_marketing_metrics( + market_observations, + marketing_margin = "marketing_margin", + channel = "channel", + weight = "volume_qtl", + R = 30, + seed = 123 + ) > stopifnot(identical(old_seed, .Random.seed)) > stopifnot(inherits(boot, "agriME_bootstrap")) > stopifnot(nrow(boot$summary) == 24L) > stopifnot(all(boot$summary$conf_low <= boot$summary$conf_high, na.rm = TRUE)) > > sens <- marketing_sensitivity( + 1900, 3150, 510, 740, + producer_change = c(0, 0.05), + cost_change = c(-0.1, 0, 0.1) + ) > stopifnot(inherits(sens, "agriME_sensitivity"), nrow(sens) == 6L) > target <- efficiency_target( + target = 2, + method = "acharya", + solve_for = "marketing_cost", + producer_price = 1900, + marketing_margin = 740 + ) > stopifnot(isTRUE(all.equal(target$required_value, 210))) > > loss <- loss_adjusted_margin(20, 28, 100, 92, 180, "lot") > stopifnot( + loss$loss_quantity == 8, + isTRUE(all.equal(loss$loss_percent, 8)), + loss$net_margin_total == 396 + ) > > # All base-graphics methods execute on a non-interactive device. > plot_file <- tempfile(fileext = ".pdf") > grDevices::pdf(plot_file) > plot(fit, type = "decomposition") > plot(fit, type = "efficiency") > plot(fit, type = "producer_share") > plot(ranking) > plot(boot, metric = "acharya_efficiency") > plot(sens, metric = "acharya_efficiency") > grDevices::dev.off() null device 1 > stopifnot(file.exists(plot_file), file.info(plot_file)$size > 0) > unlink(plot_file) > > > proc.time() user system elapsed 0.40 0.06 0.45