diff --git a/DESCRIPTION b/DESCRIPTION index f4548ca..5ecc33d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: gosset Type: Package Title: Tools for Data Analysis in Experimental Agriculture -Version: 1.4 +Version: 1.4.1 Authors@R: c(person("Kauê", "de Sousa", email = "desousa.kaue@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-7571-7845")), diff --git a/R/worth_map.R b/R/worth_map.R index 4dd3e6b..688284b 100755 --- a/R/worth_map.R +++ b/R/worth_map.R @@ -8,6 +8,8 @@ #' an object of class \code{PlackettLuce} or #' a list objects of class \code{PlackettLuce} #' @param labels a vector with the name of models in \var{object} +#' @param labels.order optional, a vector to determine the order of labels +#' @param items.order optional, a vector to determine the order of items #' @param ... additional arguments passed to methods #' @examples #' library("psychotree") @@ -106,20 +108,41 @@ worth_map.default = function(object, ...) { #' @method worth_map list #' @rdname worth_map #' @export -worth_map.list = function(object, labels, ...) { +worth_map.list = function(object, + labels, + labels.order = NULL, + items.order = NULL, ...) { + + if (is.null(labels.order)) { + lvls = labels + } else { + lvls = labels.order + } - winprobs = .combine_coeffs(object, log = TRUE, vcov = FALSE, ...) + winprobs = .combine_coeffs(object, log = TRUE, ...) # add name of features names(winprobs) = labels + if (is.null(items.order)) { + order_items = order(exp(winprobs[,lvls[[1]]])) + order_items = rownames(winprobs)[order_items] + } else { + order_items = items.order + } + + + winprobs = data.frame(items = rep(dimnames(winprobs)[[1]], times = ncol(winprobs)), labels = rep(dimnames(winprobs)[[2]], each = nrow(winprobs)), winprob = as.numeric(unlist(winprobs))) - winprobs$labels = factor(winprobs$labels, levels = labels) + winprobs$labels = factor(winprobs$labels, levels = rev(lvls)) + + winprobs$items = factor(winprobs$items, + levels = rev(order_items)) items = winprobs$items winprob = winprobs$winprob @@ -142,16 +165,13 @@ worth_map.list = function(object, labels, ...) { direction = 1, na.value = "white", name = "") + - ggplot2::theme_bw() + - theme(axis.text = ggplot2::element_text(color = "grey20"), - strip.text.x = ggplot2::element_text(color = "grey20"), - axis.text.x = ggplot2::element_text(angle = 40, vjust = 1, hjust = 1), - axis.text.y = ggplot2::element_text(angle = angle, vjust = 1, hjust = 1), - panel.grid = ggplot2::element_blank()) - ggplot2::labs(x = "", - y = "", - fill = "") - + ggplot2::theme_minimal() + + ggplot2::theme(axis.text = ggplot2::element_text(color = "grey20"), + strip.text.x = ggplot2::element_text(color = "grey20"), + axis.text.x = ggplot2::element_text(angle = 40, vjust = 1, hjust = 1), + axis.text.y = ggplot2::element_text(angle = angle, vjust = 1, hjust = 1), + panel.grid = ggplot2::element_blank()) + + ggplot2::labs(x = "", y = "") return(p) @@ -162,11 +182,14 @@ worth_map.list = function(object, labels, ...) { #'Combine coefficients from PlackettLuce models #' @param x a list with PlackettLuce models #' @param na.replace logical, to replace or keep NAs -#' @param ... further arguments passed to methods +#' @param ... additional arguments passed to methods #' @noRd .combine_coeffs = function(x, na.replace = TRUE, rescale = TRUE, ...) { - coeffs = lapply(x, function(y) {psychotools::itempar(y, ...)}) + coeffs = lapply(x, function(y) { + #psychotools::itempar(y, ...) + stats::coefficients(y, ...) + }) items = unique(unlist(lapply(coeffs, names))) diff --git a/dev/dominance-analysis.R b/dev/dominance-analysis.R new file mode 100644 index 0000000..4d4db89 --- /dev/null +++ b/dev/dominance-analysis.R @@ -0,0 +1,82 @@ +library(dominanceanalysis) +library(caTools) +library("gosset") +library("ClimMobTools") +library("PlackettLuce") +library("ggplot2") +library("patchwork") + +data("cassava", package = "gosset") + +dat = cassava + +head(dat[, 1:11]) + +keep = unlist(lapply(dat[1:ncol(dat)], function(x) sum(is.na(x)))) + +keep = keep == 0 + +dat = dat[, keep] + +names(dat) + +# extract list of traits from the data +trait_list = getTraitList(dat, pattern = c("_pos", "_neg")) + +# trait names extracted from the function +traits = unlist(lapply(trait_list, function(x) x$trait_label)) + +# clean trait names and put them title case +traits = gsub("(^|[[:space:]])([[:alpha:]])", "\\1\\U\\2", traits, perl = TRUE) + +traits + +pack = c("option_a", "option_b", "option_c") + +items = sort(unique(unlist(dat[pack]))) + +check = "Obasanjo-2" + +ov = which(traits %in% "Overall") + +R = lapply(trait_list, function(x) { + rank_tricot(dat, + items = pack, + input = x$string, + validate.rankings = TRUE) +}) + +mod = lapply(R, PlackettLuce) + +worth = lapply(mod, function(x){ + z = resample(x, log = TRUE, bootstrap = TRUE, n1 = 10, seed = 1432)$estimate + #log(z) +}) + +worth = as.data.frame(do.call("cbind", worth)) + +names(worth) = traits + +head(worth) + +plot(worth$Colour, worth$Overall) +plot(worth$Stretchability, worth$Overall) +plot(worth$Taste, worth$Overall) + +modpres = lm(Overall ~ Taste + Stretchability + Colour, data = worth) + +summary(modpres) + +dapres = dominanceAnalysis(modpres) + +getFits(dapres,"r2") + +dominanceMatrix(dapres, type="complete",fit.functions = "r2", ordered=TRUE) + +contributionByLevel(dapres,fit.functions="r2") + +plot(dapres, which.graph ="conditional",fit.function = "r2") + theme_minimal() + +dom = averageContribution(dapres,fit.functions = "r2") + + diff --git a/docs/404.html b/docs/404.html index 06c5031..3909c2a 100644 --- a/docs/404.html +++ b/docs/404.html @@ -39,7 +39,7 @@
diff --git a/docs/CODE_OF_CONDUCT.html b/docs/CODE_OF_CONDUCT.html index b9333a1..cd00044 100644 --- a/docs/CODE_OF_CONDUCT.html +++ b/docs/CODE_OF_CONDUCT.html @@ -17,7 +17,7 @@ diff --git a/docs/CONTRIBUTING.html b/docs/CONTRIBUTING.html index 8d6dd41..5082ed5 100644 --- a/docs/CONTRIBUTING.html +++ b/docs/CONTRIBUTING.html @@ -17,7 +17,7 @@ diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html index e4496f9..543274a 100644 --- a/docs/LICENSE-text.html +++ b/docs/LICENSE-text.html @@ -17,7 +17,7 @@ diff --git a/docs/LICENSE.html b/docs/LICENSE.html index d1244e6..caf96e2 100644 --- a/docs/LICENSE.html +++ b/docs/LICENSE.html @@ -17,7 +17,7 @@ diff --git a/docs/articles/index.html b/docs/articles/index.html index 2e0a65e..e06575a 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -17,7 +17,7 @@ diff --git a/docs/articles/vignette-1-trait-prioritization-and-crop-performance.html b/docs/articles/vignette-1-trait-prioritization-and-crop-performance.html index ef1937b..82096bc 100644 --- a/docs/articles/vignette-1-trait-prioritization-and-crop-performance.html +++ b/docs/articles/vignette-1-trait-prioritization-and-crop-performance.html @@ -38,7 +38,7 @@ diff --git a/docs/articles/vignette-1-trait-prioritization-and-crop-performance_files/figure-html/worthmap-1.png b/docs/articles/vignette-1-trait-prioritization-and-crop-performance_files/figure-html/worthmap-1.png index 60424d9..eb67f1b 100644 Binary files a/docs/articles/vignette-1-trait-prioritization-and-crop-performance_files/figure-html/worthmap-1.png and b/docs/articles/vignette-1-trait-prioritization-and-crop-performance_files/figure-html/worthmap-1.png differ diff --git a/docs/articles/vignette-2-gari-eba-consumer-testing.html b/docs/articles/vignette-2-gari-eba-consumer-testing.html index 5ac53d3..0301bf4 100644 --- a/docs/articles/vignette-2-gari-eba-consumer-testing.html +++ b/docs/articles/vignette-2-gari-eba-consumer-testing.html @@ -38,7 +38,7 @@ @@ -103,37 +103,38 @@Here, I present a workflow to analyze data from a consumer preference -trial executed in Nigeria and Cameroon by the International Institute of -Tropical Agriculture (IITA) under the RTBFoods project (https://rtbfoods.cirad.fr). Consumer testing was carried -out with 1,000 participants in 2022 in Cameroon and Nigeria using the -tricot approach [1]. Diverse consumers in -villages, towns, and cities evaluated the overall acceptability of -gari-eba made from 13 cassava (Manihot esculenta Crantz) -genotypes. Apart from the overall preference of the samples, the -following traits were evaluated for eba based on triangulated insights -obtained through earlier surveys and participatory work in the three -areas: Nigeria (Osun and Benue States): color, smoothness, moldability, -stretchability, and taste. Cameroon (Littoral zone): color, odor, taste, -firmness, and stretchability.
-Traits in common are color, taste, and stretchability. The results of -this study were published by Olaosebikan et al. (2023)[2], and a deeper analysis for the Nigerian -subset, linking the consumer data to laboratory instrumental metrics, -was published by Alamu et al. (2023)[3]. -The present vignette does not intend to replicate the results of these -studies. Instead, it presents an alternative workflow to what was -developed in the study. For the replication data on Olaosebikan et -al. (2023), please visit https://github.com/AgrDataSci/rtbfoods-consumer-testing. -For the replication data on Alamu et al. (2023), please visit https://github.com/AgrDataSci/cassava-consumer-iita/.
+This vignette demonstrates a workflow for analyzing consumer +preference data from decentralized trials of cassava (Manihot +esculenta Crantz) varieties in Nigeria and Cameroon. Using the +tricot approach [1], 1,000 participants +evaluated gari-eba made from 13 cassava genotypes in 2022. The trial was +implemented by the International Institute of Tropical Agriculture +(IITA) under the RTBFoods project (https://rtbfoods.cirad.fr). Participants assessed +overall preference and traits such as color, stretchability, and taste, +reflecting diverse consumer priorities.
+Building on studies by Olaosebikan et al. (2023) [2] and Alamu et al. (2023) [3], this vignette introduces an alternative +workflow. It leverages statistical models, such as the Plackett-Luce +model, to analyze overall preference, explore trait-specific +performance, and account for consumer heterogeneity. By segmenting the +data by groups like country, the analysis uncovers context-specific +varietal performance and identifies the best varieties for specific +groups.
+Additionally, a weighted selection index is proposed to integrate +multiple traits, enabling a data-driven approach to ranking varieties. +This workflow emphasizes a consumer- and market-oriented approach, +offering insights into plant breeding and selection strategies that +align with local preferences and environmental contexts. The +selection index approach is under development and open for improvements, +suggestions and comments.
+The cassava
data is a data frame with 1,000 observations
and 27 variables, which are described in the data documentation with
?cassava
. This vignette will require the packages
PlackettLuce [4], ClimMobTools [5], ggplot2 [6],
and patchwork [7].
library("gosset")
library("ClimMobTools")
@@ -285,12 +286,9 @@ Assess the full data
-worth_map(mod, labels = traits) +
- labs(x = "", y = "") +
- scale_fill_distiller(palette = "BrBG",
- direction = 1,
- na.value = "white",
- name = "")
worth_map(mod,
+ labels = traits,
+ labels.order = c("Overall", "Taste", "Stretchability", "Colour"))
The worth map confirms the superiority of TMS6, Sape and TMEB1 across the traits, but also presents Madame among the top varieties for color. @@ -359,9 +357,11 @@
The segmented analysis reveals contrasting results compared to the previous analysis using the full dataset. It highlights the superiority of TMS6 and TMEB1 in Nigeria, and Game Changer and Sape in Cameroon. This approach provides a visual method to select the best variety -overall for each group. To account for all traits in a data-driven -manner when selecting varieties, I propose a selection index approach. -This method calculates weighted estimates and derives a selection score -that represents the overall performance of the varieties across all -traits.
+overall for each group. +To account for all traits in a data-driven manner when selecting +varieties, I propose a selection index approach. This method calculates +weighted estimates and derives a selection score that represents the +overall performance of the varieties across all traits.
Suppose we have three varieties with standardized probabilities for each trait:
Kendall's W (coefficient of concordance) |
+ |
+ + | +Kendall's tau permutation test |
diff --git a/docs/reference/kendallTau.html b/docs/reference/kendallTau.html index c234a9e..7337029 100644 --- a/docs/reference/kendallTau.html +++ b/docs/reference/kendallTau.html @@ -24,7 +24,7 @@ @@ -130,7 +130,7 @@ |