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() stopifnot(file.exists(plot_file), file.info(plot_file)$size > 0) unlink(plot_file)