Skip to content

Commit 2f8c456

Browse files
committed
add ms_merge_observations() closes #102
1 parent b090ac5 commit 2f8c456

File tree

7 files changed

+152
-19
lines changed

7 files changed

+152
-19
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ S3method(modelStudio,dalex._explainer.object.Explainer)
44
S3method(modelStudio,explainer)
55
S3method(modelStudio,python.builtin.object)
66
export(modelStudio)
7+
export(ms_merge_observations)
78
export(ms_options)
89
export(ms_update_observations)
910
export(ms_update_options)

NEWS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
* added new parameter to `modelStudio()`: `N_sv = 3*N`, which by default decreases the number of observations used for the calculation of `Shapley Values` (rows in `data`)
66
* `margin_left = NULL` by default and it is adjusted based on the length of variable names
77
* the first plot opened in the dashboard is now `FI` instead of `BD` by default
8-
* add the `verbose` parameter to `modelStudio()` as an alias to `show_info` [(#101)](https://github.com/ModelOriented/modelStudio/issues/101)
9-
8+
* added the `verbose` parameter to `modelStudio()` as an alias to `show_info` [(#101)](https://github.com/ModelOriented/modelStudio/issues/101)
9+
* add new `ms_merge_observations()` function that merges local explanation of observations from multiple `modelStudio` objects [(#102)](https://github.com/ModelOriented/modelStudio/issues/102)
1010

1111
# modelStudio 2.1.2
1212
* fixed an error in `modelStudio()` when data had only one variable [(#99)](https://github.com/ModelOriented/modelStudio/issues/99)

R/ms_merge_observations.R

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#' @title Merge the observations of modelStudio objects
2+
#'
3+
#' @description
4+
#' This function merges local explanations from multiple \code{modelStudio} objects into one.
5+
#'
6+
#' @param ... \code{modelStudio} objects created with \code{modelStudio()}.
7+
#'
8+
#' @return An object of the \code{r2d3, htmlwidget, modelStudio} class.
9+
#'
10+
#' @references
11+
#'
12+
#' \itemize{
13+
#' \item The input object is implemented in \href{https://modeloriented.github.io/DALEX/}{\bold{DALEX}}
14+
#' \item Feature Importance, Ceteris Paribus, Partial Dependence and Accumulated Dependence explanations
15+
#' are implemented in \href{https://modeloriented.github.io/ingredients/}{\bold{ingredients}}
16+
#' \item Break Down and Shapley Values explanations are implemented in
17+
#' \href{https://modeloriented.github.io/iBreakDown/}{\bold{iBreakDown}}
18+
#' }
19+
#'
20+
#' @seealso
21+
#' Vignettes: \href{https://modelstudio.drwhy.ai/articles/ms-r-python-examples.html}{\bold{modelStudio - R & Python examples}}
22+
#' and \href{https://modelstudio.drwhy.ai/articles/ms-perks-features.html}{\bold{modelStudio - perks and features}}
23+
#'
24+
#' @examples
25+
#' library("DALEX")
26+
#' library("modelStudio")
27+
#'
28+
#'
29+
#' @export
30+
#' @rdname ms_merge_observations
31+
ms_merge_observations <- function(...) {
32+
33+
#:# extract data
34+
obs_list <- list()
35+
var_list <- list()
36+
dropdown_df <- list()
37+
for (object in list(...)) {
38+
stopifnot("modelStudio" %in% class(object))
39+
temp <- jsonlite::fromJSON(object$x$data, simplifyVector = FALSE)
40+
obs_list <- c(obs_list, temp[[1]])
41+
var_list <- c(var_list, object$x$options$variable_names)
42+
dropdown_df <- rbind(
43+
dropdown_df,
44+
jsonlite::fromJSON(object$x$options$drop_down_data,
45+
simplifyVector = FALSE,
46+
simplifyDataFrame = TRUE)
47+
)
48+
}
49+
50+
#:# create new data
51+
temp <- jsonlite::toJSON(list(obs_list, temp[[2]], temp[[3]],
52+
temp[[4]], temp[[5]], temp[[6]]),
53+
auto_unbox = TRUE)
54+
widget_id <- paste0("widget-", digest::digest(temp))
55+
56+
#:# extract old options and update them
57+
new_options <- object$x$options
58+
new_options$widget_id <- widget_id
59+
new_options$variable_names <- unique(var_list)
60+
new_options$footer_text <- paste0("Site built with modelStudio v",
61+
as.character(packageVersion("modelStudio")),
62+
" on ",
63+
format(Sys.time(), usetz = FALSE))
64+
new_options$drop_down_data <- jsonlite::toJSON(dropdown_df)
65+
66+
options("r2d3.shadow" = FALSE) # set this option to avoid using shadow-root
67+
68+
model_studio <- r2d3::r2d3(
69+
data = temp,
70+
script = system.file("d3js/modelStudio.js", package = "modelStudio"),
71+
dependencies = list(
72+
system.file("d3js/hackHead.js", package = "modelStudio"),
73+
system.file("d3js/myTools.js", package = "modelStudio"),
74+
system.file("d3js/d3-tip.js", package = "modelStudio"),
75+
system.file("d3js/d3-simple-slider.min.js", package = "modelStudio"),
76+
system.file("d3js/d3-interpolate-path.min.js", package = "modelStudio"),
77+
system.file("d3js/generatePlots.js", package = "modelStudio"),
78+
system.file("d3js/generateTooltipHtml.js", package = "modelStudio")
79+
),
80+
css = system.file("d3js/modelStudio.css", package = "modelStudio"),
81+
options = new_options,
82+
d3_version = "4",
83+
sizing = object$sizingPolicy,
84+
elementId = widget_id,
85+
width = new_options$facet_dim[2]*(new_options$w + new_options$margin_left + new_options$margin_right),
86+
height = 100 + new_options$facet_dim[1]*(new_options$h + new_options$margin_top + new_options$margin_bottom)
87+
)
88+
89+
model_studio$x$script <- remove_file_paths(model_studio$x$script, "js")
90+
model_studio$x$style <- remove_file_paths(model_studio$x$style, "css")
91+
92+
class(model_studio) <- c(class(model_studio), "modelStudio")
93+
94+
model_studio
95+
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The main `modelStudio()` function computes various (instance and model-level) ex
1919
<a href="https://iema.drwhy.ai">Interactive EMA<a> &emsp;
2020
</b></p>
2121

22-
[![](man/figures/demo_small.gif)](https://rai-covid.drwhy.ai)
22+
[![](man/figures/demo_small.gif)](https://modelstudio.drwhy.ai/demo.html)
2323

2424
The `modelStudio` package is a part of the [**DrWhy.AI**](http://drwhy.ai) universe.
2525

@@ -55,7 +55,7 @@ modelStudio(explainer)
5555

5656
[Save the output](https://modelstudio.drwhy.ai/#save--share) in the form of a HTML file - [**Demo Dashboard**](https://modelstudio.drwhy.ai/demo.html).
5757

58-
[![](man/figures/demo_big.gif)](https://rai-covid.drwhy.ai)
58+
[![](man/figures/demo_big.gif)](https://modelstudio.drwhy.ai/demo.html)
5959

6060
## R & Python examples [more](https://modelstudio.drwhy.ai/articles/ms-r-python-examples.html)
6161

man/happiness_train.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/ms_merge_observations.Rd

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test_ms_update_observations.R

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,26 @@ if (requireNamespace("ranger", quietly=TRUE)) {
1010
testthat::expect_silent(ms)
1111
})
1212

13-
new_ms1 <- modelStudio::ms_update_observations(ms, explain_rf, B = 2, show_info = v)
14-
new_ms2 <- modelStudio::ms_update_observations(ms, explain_rf, B = 2, show_info = v,
15-
new_observation = apartments[100:101,],
16-
overwrite = FALSE)
17-
new_ms3 <- modelStudio::ms_update_observations(ms, explain_rf, B = 2, show_info = v,
18-
new_observation = apartments[1:2,],
19-
overwrite = TRUE)
20-
2113
testthat::test_that("ms_update_observations", {
14+
testthat::expect_silent(new_ms1 <- modelStudio::ms_update_observations(ms, explain_rf, B = 2,
15+
show_info = v))
2216
testthat::expect_is(new_ms1, "modelStudio")
23-
testthat::expect_silent(modelStudio::ms_update_observations(ms, explain_rf, B = 2, show_info = v))
24-
testthat::expect_is(new_ms2, "modelStudio")
25-
testthat::expect_silent(modelStudio::ms_update_observations(ms, explain_rf, B = 2, show_info = v,
17+
18+
testthat::expect_silent(new_ms2 <- modelStudio::ms_update_observations(ms, explain_rf, B = 2,
19+
show_info = v,
2620
new_observation = apartments[100:101,],
2721
overwrite = FALSE))
28-
testthat::expect_is(new_ms3, "modelStudio")
29-
testthat::expect_silent(modelStudio::ms_update_observations(ms, explain_rf, B = 2, show_info = v,
22+
testthat::expect_is(new_ms2, "modelStudio")
23+
24+
testthat::expect_silent(new_ms3 <- modelStudio::ms_update_observations(ms, explain_rf, B = 2,
25+
show_info = v,
3026
new_observation = apartments[1:2,],
3127
overwrite = TRUE))
28+
testthat::expect_is(new_ms3, "modelStudio")
29+
30+
testthat::test_that("ms_merge_observations", {
31+
testthat::expect_silent(merged_ms <- ms_merge_observations(new_ms1, new_ms2, new_ms3))
32+
testthat::expect_is(merged_ms, "modelStudio")
33+
})
3234
})
33-
3435
}

0 commit comments

Comments
 (0)