Title: | 'DEXi' Library |
---|---|
Description: | A software package for using 'DEXi' models. 'DEXi' models are hierarchical qualitative multi-criteria decision models developed according to the method DEX (Decision EXpert, <https://dex.ijs.si/documentation/DEX_Method/DEX_Method.html>), using the program 'DEXi' (<https://kt.ijs.si/MarkoBohanec/dexi.html>) or 'DEXiWin' (<https://dex.ijs.si/dexisuite/dexiwin.html>). A typical workflow with 'DEXiR' consists of: (1) reading a '.dxi' file, previously made using the 'DEXi' software (function read_dexi()), (2) making a data frame containing input values of one or more decision alternatives, (3) evaluating those alternatives (function evaluate()), (4) analyzing alternatives (selective_explanation(), plus_minus(), compare_alternatives()), (5) drawing charts. 'DEXiR' is restricted to using models produced externally by the 'DEXi' software and does not provide functionality for creating and/or editing 'DEXi' models directly in 'R'. |
Authors: | Marko Bohanec [aut, cre] |
Maintainer: | Marko Bohanec <[email protected]> |
License: | MIT + file LICENSE |
Version: | 1.0.2 |
Built: | 2024-12-17 06:31:05 UTC |
Source: | CRAN |
DEXiR is a software package for using DEXi models in R. The main function is evaluating decision alternatives using a model previously developed by DEXi software.
DEXi models are hierarchical qualitative rule-based multi-criteria decision models developed using the method DEX (Decision EXpert, https://en.wikipedia.org/wiki/Decision_EXpert), using the program DEXi (https://kt.ijs.si/MarkoBohanec/dexi.html) or DEXiWin (https://dex.ijs.si/dexisuite/dexiwin.html).
In general, a DEXi model consists of a hierarchy of qualitative (symbolic linguistic, discrete) variables, called attributes. Each attribute represents some observable property (such as Price or Performance) of decision alternatives under study. An attribute can take values from a set of words (such as "low; medium; high" or "unacc; acc; good; exc"), which is usually small (up to five elements) and preferentially ordered from "bad" to "good" values.
The hierarchy of attributes represents a decomposition of a decision problem into sub-problems, so that higher-level attributes depend on the lower-level ones. Consequently, the terminal nodes represent inputs, and non-terminal attributes represent the outputs of the model. Among these, the most important are one or more root attributes, which represent the final evaluation(s) of the alternatives.
The evaluation of decision alternatives (i.e., hierarchical aggregation of values from model inputs to outputs) is governed by decision rules, defined for each non-terminal attribute by the creator of the model (usually referred to as a "decision maker").
DEX (Decision EXpert) refers to a general multi-attribute decision modeling method, characterized by using qualitative attribute hierarchies and decision tables. For further information, see (Trdin, Bohanec, 2018) and (Bohanec, 2022).
DEXi ("DEX for instruction") refers to DEXi software.
DEXi implements a subset of DEX, for instance, it is restricted to set-based evaluation methods.
DEXi supports the creation and editing of DEXi models, which are saved on .dxi
files and
subsequently read by DEXiR for processing in R. For further information on DEXi, see
https://kt.ijs.si/MarkoBohanec/dexi.html.
A new backward-compatible implementation of DEXi, aimed at gradually replacing it in the future. For further information on DEXiWin and related software, see https://dex.ijs.si/dexisuite/dexisuite.html.
DEXiR is this R package. It is capable of reading and processing DEXi models with some extensions towards the full DEX (for example, using value distributions).
Models developed using the DEXi software are stored in XML-formatted .dxi
files. In
order to use DEXi models in R, DEXiR supports the following tasks:
Reading DEXi models from .dxi
files into the R environment, using read_dexi
.
Making data frames containing data (both input and output) about considered decision alternatives,
using set_alternative
.
Evaluating decision alternatives, using evaluate
.
Analyzing alternatives (selective_explanation
, plus_minus
,
compare_alternatives
).
Drawing charts.
By default, evaluation is based on sets, which is a standard evaluation procedure of DEXi. DEXiR extends this by supporting:
evaluations using probabilistic and fuzzy value distributions (see evaluate
);
"pruned" evaluation, when the evaluation starts from selected non-terminal attribute(s) upwards.
DEXiR has been designed to facilitate using DEXi models in R produced externally by the DEXi software. DEXiR does not provide any explicit means for creating and/or editing DEXi models in R.
This example uses a simple DEXi model for evaluating cars, which is distributed together with the DEXi software (including DEXiR) and is used throughout DEX literature to illustrate the methodological approach (https://en.wikipedia.org/wiki/Decision_EXpert).
First, this model is loaded into R and printed as follows:
> Car <- read_dexi("data/Car.dxi") > Car DEXi Model: CAR_MODEL Description: Car demo index id structure scale funct [1] CAR_MODEL CAR_MODEL [2] CAR +- CAR unacc; acc; good; exc (+) 12 3x4 [3] PRICE |- PRICE high; medium; low (+) 9 3x3 [4] BUY.PRICE | |- BUY.PRICE high; medium; low (+) [5] MAINT.PRICE | +- MAINT.PRICE high; medium; low (+) [6] TECH.CHAR. +- TECH.CHAR. bad; acc; good; exc (+) 9 3x3 [7] COMFORT |- COMFORT small; medium; high (+) 36 3x4x3 [8] X.PERS | |- #PERS to_2; 3-4; more (+) [9] X.DOORS | |- #DOORS 2; 3; 4; more (+) [10] LUGGAGE | +- LUGGAGE small; medium; big (+) [11] SAFETY +- SAFETY small; medium; high (+)
Rows in the table correspond to individual attributes. The columns represent the following:
index
Indices of attributes.
id
Unique attribute names, generated by DEXiR from original DEXi names, in order to provide syntactically correct variable names in R and allow unambiguous referencing of attributes.
structure
The hierarchical structure of attributes, named as in the original DEXi model.
scale
Value scales associated with each attribute. The symbol "(+)" indicates that the corresponding scale is ordered preferentially in increasing order.
funct
Information about the size (number of rules) and dimensions of the corresponding decision tables.
Looking at the structure of attributes, please notice that the attribute at index [1]
is virtual and
does not actually appear in the original DEXi model. It is necessary in DEXiR to facilitate models that
have multiple root attributes. The "real" root of the Car model is actually [2]
CAR. It depends on
two lower-level attributes, PRICE and TECH.CHAR. These are decomposed further. Overall, the model consists of
six input (basic) attributes: BUY.PRICE, MAINT.PRICE, X.PERS, X.DOORS, LUGGAGE and SAFETY, and
four output (aggregate) attributes: CAR, PRICE, TECH.CHAR. and COMFORT.
Among the latter, CAR is the most important and represents the overall evaluation of cars.
The next step usually consists of defining a data frame representing decision alternatives (i.e., cars in this case). The Car model already comes with a data table about two cars:
> Car$alternatives name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 Car1 4 3 2 3 4 3 3 3 3 3 2 Car2 3 2 2 2 3 3 3 3 3 2
In this data frame, attribute values are represented by ordinal numbers w.r.t. the corresponding scales.
A more readable output can be made using DexiModel$as_character
:
> Car$as_character(Car$alternatives) name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 Car1 exc low medium low exc high more 4 big high 2 Car2 good medium medium medium good high more 4 big medium
This data can be edited using common R data.frame functions. Also, DEXiR provides the method
DexiModel$alternative
for defining a single decision alternative, for example:
> alt <- Car$alternative("MyCar1", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") > alt name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 MyCar1 NA NA 3 2 NA NA 3 3 2 2
Finally, such data tables can be evaluated using DexiModel$evaluate
:
> eval <- Car$evaluate(alt) > eval name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 MyCar1 4 3 3 2 3 3 3 3 2 2 > Car$as_character(eval) name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 MyCar1 exc low low medium good high more 4 medium medium
Once defined and evaluated, alternatives can be analysed further. DEXiR provides three analysis methods:
selective_explanation
Exposing particular weak and strong points of alternatives.
plus_minus
analysisExploring effects of changing individual attributes to evaluation results.
compare_alternatives
Comparison of an alternative with other alternatives.
Examples:
> Car$selective_explanation(1) Selective explanation of Car1 Weak points: None Strong points: id structure Car1 CAR.1 +-CAR 4 PRICE |-PRICE 3 MAINT.PRICE | +-MAINT.PRICE 3 TECH.CHAR. +-TECH.CHAR. 4 COMFORT |-COMFORT 3 X.PERS | |-#PERS 3 LUGGAGE | +-LUGGAGE 3 SAFETY +-SAFETY 3 > Car$plus_minus(1, as_character = TRUE) id structure -2 -1 CAR.1=exc 1 BUY.PRICE | |-BUY.PRICE [ unacc medium exc MAINT.PRICE | +-MAINT.PRICE unacc exc low ] X.PERS | |-#PERS unacc exc more ] X.DOORS | |-#DOORS unacc exc 4 exc LUGGAGE | +-LUGGAGE unacc exc big ] SAFETY +-SAFETY unacc exc high ] > Car$compare_alternatives(1, as_character = TRUE) id structure Car1 Car2 CAR CAR NULL NULL CAR.1 +-CAR exc > good PRICE |-PRICE low > medium BUY.PRICE | |-BUY.PRICE medium MAINT.PRICE | +-MAINT.PRICE low > medium TECH.CHAR. +-TECH.CHAR. exc > good COMFORT |-COMFORT high X.PERS | |-#PERS more X.DOORS | |-#DOORS 4 LUGGAGE | +-LUGGAGE big SAFETY +-SAFETY high > medium
Evaluation results can be drawn on charts. DEXiR provides four charts that display multiple alternatives:
plotalt1
with respect to a single attribute, drawing a scatterplot "alternatives by attribute-values"
plotalt2
with respect to two attributes, drawing a scatterplot "attribute1 by attribute2"
plotalt_parallel
with respect to multiple attributes, drawing evaluation results using parallel axes
plotalt_radar
with respect to multiple attributes, drawing evaluation results on a radar chart
The latter two plots scale evaluation results to the [0:1]
interval.
Evaluation values represented by sets or distributions are plotted either as intervals
(aggregate = "minmax"
) or are aggregated to a single value
(aggregate = "min"
, "max"
or "mean"
).
Examples:
Plot all Car alternatives with respect to Car$first() ("CAR.1")) > plotalt1(Car) Plot evaluation results of all Car alternatives with respect to attribute "PRICE" > plotalt1(Car, "PRICE") Draw "TECH.CHAR." by "PRICE" scatterplot of all Car alternatives > plotalt2(Car, "TECH.CHAR.", "PRICE") Draw a "TECH.CHAR." by "PRICE" scatterplot of the second Car alternative > plotalt2(Car, "TECH.CHAR.", "PRICE", 2) Draw all Car alternatives on parallel axes > plotalt_parallel(Car) Draw all Car alternatives on a radar chart > plotalt_radar(Car)
DEXi values are used throughout DEXi models.
They provide input values and carry results of evaluations in data frames that contain data
about decision alternatives.
Values are also used in definitions of DexiFunctions and are returned by
DexiFunction$evaluate
when evaluating some function for a given set of arguments.
In DEXi, values are always bound to the context provided by a DexiScale. Since each fully defined DexiAttribute is associated with some scale, we can generalize the scale context to attributes and speak about "assigning some value to an attribute".
The scale type determines the type and possible range of values that can be assigned to an attribute. DEXiR implements two scale types: DexiContinuousScale and DexiDiscreteScale. Regarding the values, the former is really simple: it allows assigning any single real number to the corresponding attribute. In other words, continuous DEXi values are of type numeric(1).
DexiDiscreteScale is the main scale type used throughout DEXi models and supports a wider range of value types.
The "normal" and most common discrete value is a "single qualitative value".
For illustration, let us use the scale composed of four qualitative values:
"unacc"
, "acc"
, "good"
, "exc"
. Then, "a single qualitative value" denotes
one of these words. Internally in DEXiR, such values are not represented by character strings, but rather
by ordinal numbers, so that ord("unacc"
) = 1, ord("acc"
) = 2, etc. Some DEXiR functions
can convert between the two representations, see DexiModel$as_character
and set_alternative()
.
In order to cope with missing, incomplete or uncertain data, DEX extends the concept of single values to value sets and distributions. In DEXiR, wherever it is possible to use a single qualitative value, it is also possible to use a value set or distribution. This is the main reason that all DEXiR data structures related to DEXi values are represented by lists rather than plain vectors. This includes all data frames that represent decision alternatives and all functions that return qualitative values. Also note that while sets are fully implemented in the current DEXi software, distributions are not and are thus considered extensions towards the full DEX method.
A DEXi value set is a subset of the full range of a DexiDiscreteScale values.
For the above example, the full range of ordinal values is 1:4
, and some possible subsets are
c(2)
, c(2, 4)
, c(1, 2, 3)
and 1:4
. Internally, sets are represented by
plain integer vectors or plain numeric vectors containing integer numbers.
A DEXi value distribution associates each DexiDiscreteScale value with some
number, generally denoted and normally expected to be in the [0,1] interval.
Depending on the context and used evaluation method (see
evaluate()
), can be
interpreted as probability or fuzzy set membership. In DEXiR, value distributions are
represented using the S3 class "distribution" (see distribution).
For example,
distribution(0.5, 0, 0.2, 0.3)
represents a value distribution over the
above scale example, assigning
to
"unacc"
,
to
"acc"
,
to
"good"
and
to
"exc"
.
Remarks:
The value distribution(0.5, 0, 0.2, 0.3)
is internally represented as c(0.5, 0, 0.2, 0.3)
,
whose class()
is "distribution"
.
Using a special class for distributions is necessary to distinguish them from sets. For instance, the
notation c(1, 1)
is ambiguous and would be interpreted differently as a set or distribution.
Some DEXiR functions (see DexiModel$as_character
and set_alternative()
)
support the formulation of distributions in the form of named vectors or lists, for instance
list(unacc=0.5, good=0.2, exc=0.3)
.
In data frames that contain data about decision alternatives, numeric vectors that contain non-integer values are implicitly interpreted as distributions rather than sets.
First, let us consider a car for which we have no evidence about its possible maintenance costs.
For the value of MAINT.PRICE
, we may use "*"
, which denotes the full range of
the corresponding attribute values (equivalent to 1:3
or c(1, 2, 3)
in this case).
Notice how the evaluation method considers all the possible values of MAINT.PRICE
and propagates them upwards.
alt <- Car$alternative("MyCar1a", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=2) Car$evaluate(alt) name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 MyCar1a 1, 4 1, 3 3 1, 2, 3 3 3 3 3 2 2
The above evaluation result is not really useful, as the car turns out to be c(1, 4)
, that is,
either "unacc"
or "exc"
, depending on maintenance costs.
Thus, let us try using value distribution for MAINT.PRICE, telling DEXiR that low maintenance costs
are somewhat unexpected () and that medium costs (
) are more likely than
high (
). Using the evaluation method
"prob"
(where 's are interpreted
as probabilities) gives the following results:
alt <- Car$alternative("MyCar1b", BUY.PRICE="low", MAINT.PRICE=distribution(0.1, 0.6, 0.3), X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=2) Car$evaluate(alt, method = "prob") name CAR PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY 1 MyCar1b 0.1, 0.0, 0.0, 0.9 0.1, 0.0, 0.9 3 0.1, 0.6, 0.3 0, 0, 1, 0 0, 0, 1 3 3 2 2
In this case, the final evaluation of CAR
is distribution(0.1, 0.0, 0.0, 0.9)
, that is,
list(unacc=0.1, exc=0.9)
. It is much more likely that MyCar1b
is "exc"
than "unacc"
.
Decision EXpert. Wikipedia, https://en.wikipedia.org/wiki/Decision_EXpert.
Trdin, N., Bohanec, M.: Extending the multi-criteria decision making method DEX with numeric attributes, value distributions and relational models. Central European Journal of Operations Research, 1-24, 2018 doi:10.1007/s10100-017-0468-9.
Bohanec, M.: DEX (Decision EXpert): A Qualitative Hierarchical Multi-criteria Method. In: Kulkarni, A.J. (ed.): Multiple Criteria Decision Making: Techniques, Analysis and Applications. Singapore: Springer, 39-78, 2022 doi:10.1007/978-981-16-7414-3_3.
DEXi: A Program for Multi-Attribute Decision Making. https://kt.ijs.si/MarkoBohanec/dexi.html.
Bohanec, M.: DEXi: Program for Multi-Attribute Decision Making, User's Manual, Version 5.04. IJS Report DP-13100, Jožef Stefan Institute, Ljubljana, 2020. https://kt.ijs.si/MarkoBohanec/pub/DEXiManual504.pdf.
Bohanec, M.: DEXiWin: DEX Decision Modeling Software, User’s Manual, Version 1.2. IJS Report DP-14741, Jožef Stefan Institute, Ljubljana, 2024. https://kt.ijs.si/MarkoBohanec/pub/2024_DP14747_DEXiWin.pdf.
DEX Software. https://dex.ijs.si.
Maintainer: Marko Bohanec [email protected] (ORCID)
Make a list of alternative
's values corresponding to attributes
.
alt_values(alt, attributes, as_character = TRUE, round = NULL)
alt_values(alt, attributes, as_character = TRUE, round = NULL)
alt |
|
attributes |
A vector of DexiAttribute objects. |
as_character |
|
round |
A single integer. An optional argument to |
character(length(attributes))
. String representation of alt
's values.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) unlist(alt_values(Car$alternatives[1,], Car$attributes, as_character = TRUE)) # c("NULL", "exc", "low", "medium", "low", "exc", "high", "more", "4", "big", "high")
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) unlist(alt_values(Car$alternatives[1,], Car$attributes, as_character = TRUE)) # c("NULL", "exc", "low", "medium", "low", "exc", "high", "more", "4", "big", "high")
Determine the function to be used in the conjunctive aggregation step of evaluate()
.
and_function(method = EnumEvalMethod, and = NULL)
and_function(method = EnumEvalMethod, and = NULL)
method |
One of: |
and |
Some conjunctive aggregation function of the form |
Returns the function and
if not NULL
.
Otherwise, it determines the result depending on method
:
Fails with an error if the result is not an R function.
Return names or IDs of DexiAttribute objects.
att_names(atts, use_id = TRUE)
att_names(atts, use_id = TRUE)
atts |
A vector of DexiAttributes. |
use_id |
Determines whether to return attribute IDs or original DEXi names. |
A character vector of attribute IDs or names.
Given a single alternative
, determine the effects of varying attribute
on target
attribute.
attribute_effect(model, attribute, alternative, target = NULL, seq = NULL, ...)
attribute_effect(model, attribute, alternative, target = NULL, seq = NULL, ...)
model |
A DexiModel object. Required. |
attribute |
A DexiAttribute with assigned discrete or continuous scale. |
alternative |
A |
target |
Target DexiAttribute. Defaults to |
seq |
A sequence of |
... |
Optional parameters passed to |
A list of target
evaluation results, indexed by the values of seq
.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") # Determine the effect of changing "SAFETY" balues on "CAR.1" attribute_effect(Car, "SAFETY", alt) # Returns a list of "CAR.1" values corresponding to consecutive values of "SAFETY" attribute_effect(Car, "LUGGAGE", alt, "TECH.CHAR.") # Returns a list of "TECH.CHAR." values corresponding to consecutive values of "LUGGAGE"
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") # Determine the effect of changing "SAFETY" balues on "CAR.1" attribute_effect(Car, "SAFETY", alt) # Returns a list of "CAR.1" values corresponding to consecutive values of "SAFETY" attribute_effect(Car, "LUGGAGE", alt, "TECH.CHAR.") # Returns a list of "TECH.CHAR." values corresponding to consecutive values of "LUGGAGE"
bounded_scale_value
is a wrapper around scale_value()
that makes sure that
the resulting values lie within the bounds set up by the scale
.
bounded_scale_value(value, scale)
bounded_scale_value(value, scale)
value |
Any DEXi value, including value sets and distributions. |
scale |
A DexiScale or derived object. |
For continuous scales, value
is returned "as is". For discrete scales, all elements
of value
that lie outside of scale$full_range()
are removed. If this results in
an empty value set or distribution, NULL
is returned.
scl <- DexiDiscreteScale(values = c("low", "med", "high")) bounded_scale_value(NA, scl) # NA bounded_scale_value(1, scl) # 1 bounded_scale_value(4, scl) # NULL bounded_scale_value(c(0, 1, 3, 4, 5), scl) # c(1, 3) bounded_scale_value(distribution(0.1, 0.2, 0.3, 0.4), scl) # distribution(0.1, 0.2, 0.3)
scl <- DexiDiscreteScale(values = c("low", "med", "high")) bounded_scale_value(NA, scl) # NA bounded_scale_value(1, scl) # 1 bounded_scale_value(4, scl) # NULL bounded_scale_value(c(0, 1, 3, 4, 5), scl) # c(1, 3) bounded_scale_value(distribution(0.1, 0.2, 0.3, 0.4), scl) # distribution(0.1, 0.2, 0.3)
Compare Alternatives Analysis: Compare alternative
with each of alternatives
.
Display only values that differ and, optionally when compare = TRUE
, include
preference-relational operators.
compare_alternatives( model, alternative, alternatives = NULL, root = NULL, compare = TRUE, deep = TRUE, print = TRUE, as_character = FALSE, round = NULL, id = NULL, evaluate = FALSE, ... )
compare_alternatives( model, alternative, alternatives = NULL, root = NULL, compare = TRUE, deep = TRUE, print = TRUE, as_character = FALSE, round = NULL, id = NULL, evaluate = FALSE, ... )
model |
A DexiModel object. Required. |
alternative |
Either a |
alternatives |
Either a |
root |
Optional DexiAttribute object.
When specified, only attributes that affect |
compare |
|
deep |
|
print |
|
as_character |
|
round |
An integer number, argument to |
id |
|
evaluate |
|
... |
Optional parameters for |
Returns or prints a data.frame
consisting of columns:
id
(if requested), structure
(if requested),
values of alternative
and comparison results for each alternative from alternatives
.
compare_two_alternatives()
, evaluate()
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Extend Car$alternatives car3 <- set_alternative(Car, Car$alternatives[2,], name = "Car3", LUGGAGE = 2) Car$alternatives[3,] <- car3 car4 <- set_alternative(Car, Car$alternatives[2,], name = "Car4", LUGGAGE = 1) # Compare Car1 with the other two, varying some arguments compare_alternatives(Car, 1, evaluate=TRUE, compare=FALSE) compare_alternatives(Car, 1, evaluate=TRUE, compare=TRUE) compare_alternatives(Car, 1, evaluate=TRUE, compare=TRUE, deep=FALSE) # Compare Car2 with Car1 compare_alternatives(Car, 2, 1) # Compare car3 with Car1 and Car2 compare_alternatives(Car, car3, 1:2) # Compare car4 with Car$alternatives compare_alternatives(Car, car4) # Compare Car$alternatives[1,] with car3 compare_alternatives(Car, 1, car3) compare_alternatives(Car, Car$alternatives[1,], car3)
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Extend Car$alternatives car3 <- set_alternative(Car, Car$alternatives[2,], name = "Car3", LUGGAGE = 2) Car$alternatives[3,] <- car3 car4 <- set_alternative(Car, Car$alternatives[2,], name = "Car4", LUGGAGE = 1) # Compare Car1 with the other two, varying some arguments compare_alternatives(Car, 1, evaluate=TRUE, compare=FALSE) compare_alternatives(Car, 1, evaluate=TRUE, compare=TRUE) compare_alternatives(Car, 1, evaluate=TRUE, compare=TRUE, deep=FALSE) # Compare Car2 with Car1 compare_alternatives(Car, 2, 1) # Compare car3 with Car1 and Car2 compare_alternatives(Car, car3, 1:2) # Compare car4 with Car$alternatives compare_alternatives(Car, car4) # Compare Car$alternatives[1,] with car3 compare_alternatives(Car, 1, car3) compare_alternatives(Car, Car$alternatives[1,], car3)
Compare alternatives alt1
and alt2
with respect to attributes
.
compare_two_alternatives(alt1, alt2, attributes, deep = TRUE)
compare_two_alternatives(alt1, alt2, attributes, deep = TRUE)
alt1 |
|
alt2 |
|
attributes |
Vector of DexiAttribute objects. |
deep |
|
numeric(length(attributes))
.
Each element represents the outcome of comparison w.r.t. the corresponding attribute.
Possible outcomes:
0
Values are equal.
-1
alt1
's value is worse than alt2
's.
+1
alt1
's value is better than alt2
's.
NA
Values are incomparable.
When deep = TRUE
, the so-called deep comparison is performed:
when the compared attribute's values are equal,
subordinate attributes are checked for differences, possibly returning
-0.5
(indicating the weak preference relation "<=") or
+0.5
(indicating the weak preference relation ">=").
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) compare_two_alternatives(Car$alternatives[1,], Car$alternatives[2,], Car$attributes) # c(NA, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1)
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) compare_two_alternatives(Car$alternatives[1,], Car$alternatives[2,], Car$attributes) # c(NA, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1)
Compare two DEXi values.
Internal representation is assumed for value1
and value2
, i.e.,
a single number, an integer vector representing a set or distribution()
.
Distributions are compared as sets.
compare_values(value1, value2)
compare_values(value1, value2)
value1 |
First value. |
value2 |
Second value. |
0
if values are equal, -1
if value1 < value2
, +1
if value1 > value2
and NA
if values are incomparable. Values are incomparable if they are of a non-DEXiValue
type or if they represent two overlapping sets.
compare_values(c(1,2), c(1,2)) # 0 compare_values(c(1,2), c(1,3)) # NA compare_values(c(1,2), c(3,4)) # -1 compare_values(c(1,2), c(2,4)) # NA compare_values(c(1,2), c(2.1,4)) # -1 compare_values(c(1,2.05), c(2.1,4)) # -1 compare_values(c(3,4), c(3,4)) # 0 compare_values(c(5,5), c(3,4)) # +1 compare_values(c(5,5), 2) # +1 compare_values(c(5,2), 2) # NA compare_values(c(5,3), 2) # +1 compare_values(distribution(5,3), 2) # NA compare_values(distribution(5,3), 5) # -1
compare_values(c(1,2), c(1,2)) # 0 compare_values(c(1,2), c(1,3)) # NA compare_values(c(1,2), c(3,4)) # -1 compare_values(c(1,2), c(2,4)) # NA compare_values(c(1,2), c(2.1,4)) # -1 compare_values(c(1,2.05), c(2.1,4)) # -1 compare_values(c(3,4), c(3,4)) # 0 compare_values(c(5,5), c(3,4)) # +1 compare_values(c(5,5), 2) # +1 compare_values(c(5,2), 2) # NA compare_values(c(5,3), 2) # +1 compare_values(distribution(5,3), 2) # NA compare_values(distribution(5,3), 5) # -1
Compare values, considering preference order
. For value arguments, see compare_values()
.
compare_values_by_preference(value1, value2, order = EnumOrder)
compare_values_by_preference(value1, value2, order = EnumOrder)
value1 |
First value. |
value2 |
Second value. |
order |
|
compare_values()
result, modified according to order
.
Results 0
(equal values) and NA
(incomparable values) are always retained.
Results -1
and +1
are retained when order="ascending"
and
reversed when order="descending"
.
When order="none"
, non-equal values return NA
.
compare_values_by_preference(1, 1, "none") # 0 compare_values_by_preference(1, 2, "none") # NA compare_values_by_preference(3, 2, "none") # NA compare_values_by_preference(1, 1, "ascending") # 0 compare_values_by_preference(1, 2, "ascending") # -1 compare_values_by_preference(3, 2, "ascending") # +1 compare_values_by_preference(1, 1, "descending") # 0 compare_values_by_preference(1, 2, "descending") # +1 compare_values_by_preference(3, 2, "descending") # -1
compare_values_by_preference(1, 1, "none") # 0 compare_values_by_preference(1, 2, "none") # NA compare_values_by_preference(3, 2, "none") # NA compare_values_by_preference(1, 1, "ascending") # 0 compare_values_by_preference(1, 2, "ascending") # -1 compare_values_by_preference(3, 2, "ascending") # +1 compare_values_by_preference(1, 1, "descending") # 0 compare_values_by_preference(1, 2, "descending") # +1 compare_values_by_preference(3, 2, "descending") # -1
Compare values value1
and value2
considering scale$order
.
Internal DEXi representation is assumed for values, i.e.,
a single number, an integer vector representing a set or distribution()
.
Distributions are compared as sets.
compare_values_on_scale(value1, value2, scale, force_compare = FALSE)
compare_values_on_scale(value1, value2, scale, force_compare = FALSE)
value1 |
First value. |
value2 |
Second value. |
scale |
Normally a |
force_compare |
|
compare_values()
result, modified according to scale$order
.
compare_values()
, compare_values_by_preference()
compare_values_on_scale(1, 2, NULL) # NA compare_values_on_scale(2, 1, "") # NA compare_values_on_scale(1, 2, NULL, force_compare = TRUE) # -1 compare_values_on_scale(2, 1, "", force_compare = TRUE) # +1 scl <- DexiDiscreteScale(values = c("a", "b", "c")) compare_values_on_scale(1, 1, scl) # 0 compare_values_on_scale(1, 2, scl) # -1 compare_values_on_scale(3, 2, scl) # +1 compare_values_on_scale(c(1, 2), c(1, 2), scl) # 0 compare_values_on_scale(c(1, 2), c(2, 3), scl) # NA scl <- DexiDiscreteScale(order = "descending", values = c("a", "b", "c")) compare_values_on_scale(1, 1, scl) # 0 compare_values_on_scale(1, 2, scl) # +1 compare_values_on_scale(3, 2, scl) # -1 compare_values_on_scale(c(1, 2), c(1, 2), scl) # 0 compare_values_on_scale(c(1, 2), c(2, 3), scl) # NA scl <- DexiDiscreteScale(order = "none", values = c("a", "b", "c")) compare_values_on_scale(1, 1, scl) # 0 compare_values_on_scale(1, 2, scl) # NA compare_values_on_scale(3, 2, scl) # NA compare_values_on_scale(c(1, 2), c(1, 2), scl) # 0 compare_values_on_scale(c(1, 2), c(2, 3), scl) # NA
compare_values_on_scale(1, 2, NULL) # NA compare_values_on_scale(2, 1, "") # NA compare_values_on_scale(1, 2, NULL, force_compare = TRUE) # -1 compare_values_on_scale(2, 1, "", force_compare = TRUE) # +1 scl <- DexiDiscreteScale(values = c("a", "b", "c")) compare_values_on_scale(1, 1, scl) # 0 compare_values_on_scale(1, 2, scl) # -1 compare_values_on_scale(3, 2, scl) # +1 compare_values_on_scale(c(1, 2), c(1, 2), scl) # 0 compare_values_on_scale(c(1, 2), c(2, 3), scl) # NA scl <- DexiDiscreteScale(order = "descending", values = c("a", "b", "c")) compare_values_on_scale(1, 1, scl) # 0 compare_values_on_scale(1, 2, scl) # +1 compare_values_on_scale(3, 2, scl) # -1 compare_values_on_scale(c(1, 2), c(1, 2), scl) # 0 compare_values_on_scale(c(1, 2), c(2, 3), scl) # NA scl <- DexiDiscreteScale(order = "none", values = c("a", "b", "c")) compare_values_on_scale(1, 1, scl) # 0 compare_values_on_scale(1, 2, scl) # NA compare_values_on_scale(3, 2, scl) # NA compare_values_on_scale(c(1, 2), c(1, 2), scl) # 0 compare_values_on_scale(c(1, 2), c(2, 3), scl) # NA
Converts a data.frame
of alternatives' data to another data.frame
. The conversion
generally involves: aggregating DEXi values originally represented by sets or distributions,
scaling aggregated values to a given interval and/or reversing values assigned to "descending"
DexiScales.
convert_alternatives( model, alternatives = NULL, interpret = c("set", "distribution", "none"), aggregate = min, omin = 0, omax = 1, map_values = TRUE, reverse_descending = TRUE, verbatim = "name", skip = NULL, continuous = convert_data_continuous, discrete = convert_data_discrete )
convert_alternatives( model, alternatives = NULL, interpret = c("set", "distribution", "none"), aggregate = min, omin = 0, omax = 1, map_values = TRUE, reverse_descending = TRUE, verbatim = "name", skip = NULL, continuous = convert_data_continuous, discrete = convert_data_discrete )
model |
A DexiModel object. Required. |
alternatives |
A |
interpret |
Values corresponding to continuous attributes are not converted nor affected by these settings. |
aggregate |
A function accepting the interpreted DEXi value (see |
omin |
|
omax |
|
map_values |
|
reverse_descending |
|
verbatim |
|
skip |
|
continuous |
A function converting a data column that corresponds to a continuous attribute.
Default: |
discrete |
A function converting a data column that corresponds to a discrete attribute.
Default: |
The rationale for convert_alternatives()
is that data frames representing alternatives,
particularly those produced by evaluate()
, generally contain DEXi values of various
and mixed data types, such as numbers and numeric vectors (sets and distributions).
As such, this data is difficult to work with in R,
as most R functions expect simpler and more uniform data structures.
convert_alternatives()
produces data frames that are more suitable for standard R data analysis
and graph drawing. However, as the conversion generally involves aggregation and mapping
of DEXi values, it may distort or lose information along the way.
A converted data.frame
.
convert_data_continuous()
, convert_data_discrete()
, scale_alternatives()
,
DEXiR-package notes on values in DEXi models.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Map Car$alternatives' values to the [0, 1] interval. convert_alternatives(Car) # name CAR.1 PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY # 1 Car1 1.0000000 1.0 0.5 1.0 1.0000000 1 1 0.6666667 1 1.0 # 2 Car2 0.6666667 0.5 0.5 0.5 0.6666667 1 1 0.6666667 1 0.5
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Map Car$alternatives' values to the [0, 1] interval. convert_alternatives(Car) # name CAR.1 PRICE BUY.PRICE MAINT.PRICE TECH.CHAR. COMFORT X.PERS X.DOORS LUGGAGE SAFETY # 1 Car1 1.0000000 1.0 0.5 1.0 1.0000000 1 1 0.6666667 1 1.0 # 2 Car2 0.6666667 0.5 0.5 0.5 0.6666667 1 1 0.6666667 1 0.5
A helper function for converting individual columns of alternatives' data.
It is assumed that data
contains numeric data corresponding to a continuous
DexiAttribute. During conversion,
values are optionally converted from some interval to another, using lin_map()
, and/or
reversed using reverse_value()
for scales whose $order = "descending"
.
convert_data_continuous( data, scale, imin = NULL, imax = NULL, omin = 0, omax = 1, map_values = TRUE, reverse_descending = TRUE )
convert_data_continuous( data, scale, imin = NULL, imax = NULL, omin = 0, omax = 1, map_values = TRUE, reverse_descending = TRUE )
data |
A vector containing floating point numbers.
Typically a |
scale |
A DexiContinuousScale object or a continuous DexiAttribute object. |
imin |
Lower input bound. Default: determined as |
imax |
Upper input bound. Default: determined as |
omin |
Lower output bound for |
omax |
Upper output bound for |
map_values |
|
reverse_descending |
|
numeric()
. Vector of converted values.
scl <- DexiContinuousScale() convert_data_continuous(c(1, 2, 5), scl) # c(0.0, 0.25, 1.00) convert_data_continuous(c(1, 2, 5), scl, imin = 0, imax = 10, omin = 0, omax = 100) # c(10, 20, 50)
scl <- DexiContinuousScale() convert_data_continuous(c(1, 2, 5), scl) # c(0.0, 0.25, 1.00) convert_data_continuous(c(1, 2, 5), scl, imin = 0, imax = 10, omin = 0, omax = 100) # c(10, 20, 50)
#' A helper function for converting individual columns of alternatives' data.
It is assumed that data
contains data corresponding to a discrete
DexiAttribute. During conversion, data
elements are converted either
to sets or distributions, and function aggregate
if applied on them.
When interpret = "set"
, values are also optionally converted to the interval [omin:omax]
,
and reversed using reverse_value()
for scales whose $order = "descending"
.
convert_data_discrete( data, scale, interpret = c("set", "distribution", "none"), aggregate = min, omin = 0, omax = 1, map_values = TRUE, reverse_descending = TRUE )
convert_data_discrete( data, scale, interpret = c("set", "distribution", "none"), aggregate = min, omin = 0, omax = 1, map_values = TRUE, reverse_descending = TRUE )
data |
A vector containing DEXi values: single numbers, integer vectors or distribuions.
Typically a |
scale |
A DexiDiscreteScale object or a discrete DexiAttribute object. |
interpret |
Either |
aggregate |
A function applied on each interpreted |
omin |
Lower output bound for |
omax |
Upper output bound for |
map_values |
|
reverse_descending |
|
Vector of converted values.
scla <- DexiDiscreteScale(values = c("L", "M", "H")) scld <- DexiDiscreteScale(values = c("L", "M", "H"), order = "descending") convert_data_discrete(c(1, 2, 3), scla) # 0.0 0.5 1.0 convert_data_discrete(c(1, 2, 3), scld) # 1.0 0.5 0.0 convert_data_discrete(list(1, 2, 3), scla) # 0.0 0.5 1.0 convert_data_discrete(list(1, 2, 3), scld) # 1.0 0.5 0.0 convert_data_discrete(list(1, 2, 3), scld, omax=10) # 10 5 0 data <- list(1, c(1,2), distribution(0.2, 0, 0.8), NA) convert_data_discrete(data, scla, omax=10) # 0 0 0 NA convert_data_discrete(data, scld, omax=10) # 10 10 10 NA convert_data_discrete(data, scla, aggregate=max, omax=10) # 0 5 10 NA convert_data_discrete(data, scla, aggregate=mean, omax=10) # 0.0 2.5 5.0 NA
scla <- DexiDiscreteScale(values = c("L", "M", "H")) scld <- DexiDiscreteScale(values = c("L", "M", "H"), order = "descending") convert_data_discrete(c(1, 2, 3), scla) # 0.0 0.5 1.0 convert_data_discrete(c(1, 2, 3), scld) # 1.0 0.5 0.0 convert_data_discrete(list(1, 2, 3), scla) # 0.0 0.5 1.0 convert_data_discrete(list(1, 2, 3), scld) # 1.0 0.5 0.0 convert_data_discrete(list(1, 2, 3), scld, omax=10) # 10 5 0 data <- list(1, c(1,2), distribution(0.2, 0, 0.8), NA) convert_data_discrete(data, scla, omax=10) # 0 0 0 NA convert_data_discrete(data, scld, omax=10) # 10 10 10 NA convert_data_discrete(data, scla, aggregate=max, omax=10) # 0 5 10 NA convert_data_discrete(data, scla, aggregate=mean, omax=10) # 0.0 2.5 5.0 NA
Make a default discrete scale quality vector depending on the scale's order
and nvals
.
default_quality(order = EnumOrder, nvals)
default_quality(order = EnumOrder, nvals)
order |
'character(1)1, one of "ascending", "descending" or "none". |
nvals |
|
character vector of length nvals
, containing
"bad"
, "none"
or "good"
.
default_quality("ascending", 5) default_quality("descending", 5) default_quality("none", 5) default_quality("ascending", 2) default_quality("ascending", 1)
default_quality("ascending", 5) default_quality("descending", 5) default_quality("none", 5) default_quality("ascending", 2) default_quality("ascending", 1)
Convert a DEXi string to logical. "TRUE"
, "T"
and "1"
are interpreted as TRUE
,
all other strings as FALSE
.
dexi_bool(x)
dexi_bool(x)
x |
character(1). |
logical(1)
.
dexi_bool("TRUE") sapply(c("TRUE", "T", "1", TRUE, 1, "FALSE", "F", "0", NULL, NA, NaN), dexi_bool)
dexi_bool("TRUE") sapply(c("TRUE", "T", "1", TRUE, 1, "FALSE", "F", "0", NULL, NA, NaN), dexi_bool)
Return the index of argument vector vec
in the decision space dim
.
The index is calculated according to DEXi's sorting rules, which are different to R's.
dexi_index(vec, dim)
dexi_index(vec, dim)
vec |
Integer vector, representing arguments of some decision rule. |
dim |
Integer vector, representing dimensions of the corresponding decision space.
Assumptions: |
Integer, index of vec
.
dexi_index(c(1,1,1), c(2,2,3)) dexi_index(c(1,1,2), c(2,2,3)) dexi_index(c(1,2,3), c(2,2,3))
dexi_index(c(1,1,1), c(2,2,3)) dexi_index(c(1,1,2), c(2,2,3)) dexi_index(c(1,2,3), c(2,2,3))
Conversion of a string to a "DEXi value" (see DEXiR-package) according to "old"
DEXi syntax. In .dxi
files, the old syntax is used with OPTION
XML tags.
The reason for replacing the old with the new syntax (see dexi_value()
) was
that the old syntax can not unambiguously represent value distributions.
dexi_option_value(x)
dexi_option_value(x)
x |
|
A numeric vector. The conversion uses rule_values(x, add = 1)
.
For special-type parameters, the conversion results are:
x result ------------------------------+------ NULL NULL a non-character object NA "" or "*" "*" a string starting with "undef" NA
DEXiR-package, dexi_value()
, rule_value()
dexi_option_value(NULL) dexi_option_value(NA) dexi_option_value("") dexi_option_value("*") dexi_option_value("undef") dexi_option_value("1") dexi_option_value("012")
dexi_option_value(NULL) dexi_option_value(NA) dexi_option_value("") dexi_option_value("*") dexi_option_value("undef") dexi_option_value("1") dexi_option_value("012")
Create a representation of DEXi's decision table in R.
dexi_table(dim, low, high = NULL)
dexi_table(dim, low, high = NULL)
dim |
An integer vector, representing dimensions of the underlying decision space. |
low |
|
high |
|
length(dim)
-dimensional matrix of rule values, which are normally single integer values,
but might also be sets of values. Each set is represented by a numeric vector.
# Converting DEXi's value strings to R's numeric vectors. dexi_table(c(2, 3), "011012") dexi_table(c(2, 3), "011012", "012112")
# Converting DEXi's value strings to R's numeric vectors. dexi_table(c(2, 3), "011012") dexi_table(c(2, 3), "011012", "012112")
Conversion of a string to a "DEXi value" (see DEXiR-package) according to "new"
DEXi syntax rules. In .dxi
files, this syntax is used in ALTERNATIVE
and
RULE
XML tags. Examples of possible options include:
x result ------------------------------+------------------------------------------------- NULL or "" NULL "*" "*" a string starting with "undef" NA "2" a single ordinal value, c(2) in this case "2.1" a single number, c(2.1) in this case "1:3" interval, equivalent to c(1, 2, 3) "{0;2;3}" a value set, equivalent to c(0, 2, 3) "<0;0.3;0.7>" a value distribution, distribution(0.0, 0.3, 0.7)
dexi_value(x, add = 0)
dexi_value(x, add = 0)
x |
character(1). |
add |
A numeric constant to be added to the result. Useful
when converting DEXi's zero-based representation to one-based representation used in R,
which requires the setting |
A single integer or real number, an integer numeric vector, or a distribution.
DEXiR-package, dexi_option_value()
, distribution
dexi_value("") dexi_value(NULL) dexi_value("*") dexi_value("UNDEF") dexi_value("2") dexi_value("2.1") dexi_value("1:3") dexi_value("{0;2;3}") dexi_value("{0;2;3}", add = 1) dexi_value("<0;0.3;0.7>")
dexi_value("") dexi_value(NULL) dexi_value("*") dexi_value("UNDEF") dexi_value("2") dexi_value("2.1") dexi_value("1:3") dexi_value("{0;2;3}") dexi_value("{0;2;3}", add = 1) dexi_value("<0;0.3;0.7>")
Interpret a string, composed of ";"
-separated numbers, as a numeric vector.
dexi_vector(x)
dexi_vector(x)
x |
|
Numeric vector.
dexi_vector("1;2") dexi_vector("1.2; 2.3")
dexi_vector("1;2") dexi_vector("1.2; 2.3")
DexiAttribute
is a RC class representing a DEXi attribute in R.
In a DEXi model, attributes are variables that represent observed properties of decision alternatives. Attributes are structured in a tree, so each attribute may, but need not, have one or more direct descendants (lower-level attributes) in the tree. Attributes without descendants are called basic and serve as model inputs. Attributes with one or more descendants are called aggregate and represent model outputs. In order to represent attribute hierarchies rather than plain trees, some attributes may be linked: two attributes of which one links to another one collectively represent, in a conceptual sense, a single attribute in the hierarchy.
When completely defined, each attribute is associated with a value scale represented by a DexiScale object. An object DexiFunction is also defined for each aggregate attribute, aimed at defining the aggregation of the attribute's inputs to values of that attribute.
name
character. Name of the attribute as defined in the original DEXi model. Notice that such names may not be unique and may contain characters that cannot be used for variable names in R.
id
character. A unique identification of the attribute in the model. Derived from name
so that it can be used as a variable name in R.
description
character. An optional textual description of the attribute.
inputs
list of DexiAttributes. A list of immediate descendants of this attribute in
the tree/hierarchy. NULL
for basic attributes.
link
DexiAttribute. NULL
or a link to another DexiAttribute
scale
DexiScale. Value scale associated with this attribute, or NULL
.
funct
DexiFunction. Aggregation function associated with this attribute, or NULL
.
parent
DexiAttribute or DexiModel (only for DexiModel$root
). Parent
attribute of this attribute in the tree/hierarchy. The DexiModel$root
's parent
is the DexiModel, which contains all those attributes.
.alternatives
list. An internal field providing temporary storage for names or values of alternatives
while reading them from a .dxi
file.
affects(ant)
ant
(as "antecedent") is some DexiAttribute
.
The function returns TRUE
if ant
lies on the path leading from this attribute
towards the root, and is therefore affected by this attribute.
count()
Return the number of input
s of this attribute.
dim()
Dimensions of the value space determined by this attribute's inputs
.
Result: a numeric vector of length equal to ninp()
, containing DexiScale$count()
of
all descendant attributes, or NA
for attributes without associated scales.
For basic attributes, dim()
returns NULL
.
initialize(
name = "",
description = "",
inputs = list(),
id = "",
link = NULL,
scale = NULL,
funct = NULL,
parent = NULL,
...
)
Initialize a DexiAttribute
object.
inp_index(inp)
Return the index of attribute inp
in inputs
of this attribute.
is_aggregate()
Logical: TRUE
for aggregate attributes (attributes whose ninp() > 0
).
is_basic(include_linked = TRUE)
Logical: TRUE
for basic attributes (attributes whose ninp() == 0
.
include_linked
determines whether linked attributes are counted as basic
(TRUE
) or not (FALSE
).
is_continuous()
Logical: Indicates whether or not this is a continuous attribute.
is_discrete()
Logical: Indicates whether or not this is a discrete attribute.
is_link()
Logical: Indicates whether or not this is a linked attribute.
level()
Return the level of this attribute in the hierarchy.
The level of DexiModel$root
is 0.
model()
Return the DexiModel
that contains this attribute.
ninp()
Return the number of input
s of this attribute.
structure()
Make an indentation string for this attribute, used for printing it in show()
.
tree_indent(none = " ", thru = "|", link = "*", last = "+", line = "-")
Construct a string for representing the indentation of this attribute in the model structure.
The arguments none
, thru
, link
, last
and line
are
character strings to be used in the construction.
verify()
Check the correctnes of a DexiAttribute
object and its fields. Result: error()
or TRUE
.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # For example, consider attribute PRICE att <- Car$attrib("PRICE") # Print fields and basic properties of att att$verify() att$name att$id att$description att_names(att$inputs) att$link att$scale att$funct att_names(att$parent) att$is_aggregate() att$is_basic() att$is_link() att$level() att$count() att$ninp() att$dim() att$model() att$structure() # Check if att affects attribute CAR att$affects(Car$attrib("CAR")) # Find the index of other attributes in att's inputs att$inp_index(Car$attrib("MAINT.PRICE")) att$inp_index(Car$attrib("CAR"))
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # For example, consider attribute PRICE att <- Car$attrib("PRICE") # Print fields and basic properties of att att$verify() att$name att$id att$description att_names(att$inputs) att$link att$scale att$funct att_names(att$parent) att$is_aggregate() att$is_basic() att$is_link() att$level() att$count() att$ninp() att$dim() att$model() att$structure() # Check if att affects attribute CAR att$affects(Car$attrib("CAR")) # Find the index of other attributes in att's inputs att$inp_index(Car$attrib("MAINT.PRICE")) att$inp_index(Car$attrib("CAR"))
DexiContinuousScale
is a RC class, derived from DexiScale
,
representing continuous value scales in R.
An attribute associated with a continuous scale can take any single numeric value from
[-Inf, +Inf]
.
DexiContinuousScale
defines two numeric bounds, called low_point
and
high_point
, such that low_point <= high_point
. These values partition
preferentially ordered scales in three preferential classes ("qualities"):
"bad"
, "none"
(in the sense of "neutral"
), and "good"
.
For a scale with order = "ascending"
, the three corresponding intervals are
[-Inf, low_point]
, (low_point, high_point)
and [high_point, +Inf]
.
For order = "descending"
, the order of qualities is reversed.
Scales with order = "none"
have only one associated quality,
"none"
, for the whole range of values.
Continuous scales are supported in DEXi Suite software (DEXiWin), but not in older DEXi Classic software (DEXi).
low_point
numeric. A bound for the quality interval [-Inf, low_point]
.
high_point
numeric. A bound for the quality interval [high_point, +Inf]
.
count()
Return the number of scale elements.
Equal to NA
for DexiScale
, 0
for DexiContinuousScale
, and
equal to nvals >= 0
for DexiDiscreteScale
.
equal(scl)
Check if this scale is equal to scale scl
. Needed for attribute linking.
initialize(order = EnumOrder, ...)
Initialize a DexiScale
object.
to_string()
Return a string representation of this scale for printing.
value_quality(value)
Return the quality (preferential class) of value
on this scale:
one of the strings "bad"
, "none"
or "good"
.
Always "none"
for DexiScale
and scales with order = "none"
.
verify()
Check the correctnes of this scale object and its fields.
Result: error()
or TRUE
.
DexiDiscreteScale
is a RC class, derived from DexiScale,
representing qualitative (symbolic, discrete, verbal) value scales in R. Such scales are
typical for DEXi models and are the only scale type supported by the DEXi software.
DEXiWin software supports both continuous and discrete scales.
An attribute associated with a discrete scale can take values from a finite (and usually small)
set of string values contained in the character vector values
. Additionally, each of these values is
associated with one of the qualities "bad"
, "none"
or "good"
.
The latter are contained in the character vector quality
,
which is of the same length as values
.
values
character. Vector of qualitative scale values.
Example: scale$values <- c("low", "medium", "high")
.
nvals
integer. Equal to length(values)
.
quality
character. Vector of qualities, corresponding to values
.
Should be the of the same length as values
.
Example: scale$quality <- c("bad", "none", "good")
.
descriptions
character. A vector of textual descriptions of the corresponding
values
. Should be of the same length as values
.
count()
Return the number of scale elements.
Equal to NA
for DexiScale
, 0
for DexiContinuousScale
, and
equal to nvals >= 0
for DexiDiscreteScale
.
equal(scl)
Check if this scale is equal to scale scl
. Needed for attribute linking.
full_range()
Return the vector that represents the full range of values on this scale.
Equal to NA
for DexiScale
and DexiContinuousScale
,
and 1 : scale$nvals
for DexiDiscreteScale
.
initialize(order = EnumOrder, ...)
Initialize a DexiScale
object.
is_discrete()
Logical: Is this scale discrete?
to_string()
Return a string representation of this scale for printing.
value_index(value)
Find the index of value
(character(1)) on this scale.
Equal to NA
for DexiScale
and DexiContinuousScale
.
With DexiDiscreteScale
objects, it returns a numeric index or NA
of value
in scale$values
.
value_quality(value)
Return the quality (preferential class) of value
on this scale:
one of the strings "bad"
, "none"
or "good"
.
Always "none"
for DexiScale
and scales with order = "none"
.
verify()
Check the correctnes of this scale object and its fields.
Result: error()
or TRUE
.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # For example, consider the scale of attribute PRICE scl <- Car$attrib("PRICE")$scale # Print fields and basic properties of scl scl$verify() scl$values scl$quality scl$descriptions scl$nvals scl$count() scl$is_discrete() scl$is_continuous() scl$to_string() scl$full_range() # Find value indices scl$value_index("medium") scl$value_index("med") # Is scl equal to the scale of BUY.PRICE? scl$equal(Car$attrib("PRICE")$scale)
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # For example, consider the scale of attribute PRICE scl <- Car$attrib("PRICE")$scale # Print fields and basic properties of scl scl$verify() scl$values scl$quality scl$descriptions scl$nvals scl$count() scl$is_discrete() scl$is_continuous() scl$to_string() scl$full_range() # Find value indices scl$value_index("medium") scl$value_index("med") # Is scl equal to the scale of BUY.PRICE? scl$equal(Car$attrib("PRICE")$scale)
DexiDiscretizeFunction
is a RC class, derived from DexiFunction.
Functions of this type discretize numerical values of continuous attributes to qualitative
values of discrete attributes. More precisely, a DexiDiscretizeFunction
can be defined
only for a discrete attribute that has exactly one continuous input. Then, the function discretizes
numeric values of the input attribute and maps them to discrete values of the parent attribute.
Objects of class DexiDiscretizeFunction
define discretization rules in terms of three lists:
values
, bounds
and assoc
. Using n <- nvals()
to denote the length of
values
, the required lengths of bounds
and assoc
are n - 1
.
The list bounds
refers to values of the input attribute and partitions its scale in n
intervals
[-Inf, bound[[1]]]
, [bound[[1]], bound[[2]]],
..., [bound[[n - 1]]], +Inf]
.
The list values
then defines the output values for each interval.
The list assoc
contains strings "up"
or "down"
that indicate to which interval,
lower or higher, belong the corresponding bounds
.
attribute
DexiAttribute. The attribute this function is associated with.
Requirements: attribute
must be discrete (i.e., associated with a DexiDiscreteScale) and
must have exactly one continuous input attribute (i.e., associated with a DexiContinuousScale).
values
A list of output values corresponding to each interval defined by bounds
.
List elements are in general value sets, i.e., integer vectors of value indices w.r.t. attribute$scale
.
bounds
A vector of numeric values that partitions the input scale in intervals.
assoc
A vector of strings "up"
or "down"
.
For each i in 1:n-1
, assoc[[i]]
indicates how to map the value of
bounds[[i]]
: to value[[i]]
("down"
) or value[[i + 1]]
("up"
).
bound_assoc(idx, default = "down")
Given idx
, a bounds
index, return the corresponing association
("down"
or "up"
).
evaluate(x)
A silent wrapper around value(x)
; it returns NULL
when
value(x)
fails with an error.
nargs()
Return the number of function arguments.
nvals()
Return the length of values
.
to_string()
Return an informative string about this function's values
and bounds
.
value(x)
Return the function value for arguments x
, where arguments are
a numeric vector of length equal to att$inputs
.
Additionally, arguments of a DexiTabularFunctions$value()
must be integer numbers,
and the argument of DexiDiscretizeFunctions$value()
must be a single number.
verify()
Check the correctnes of this function object and its fields.
Result: error()
or TRUE
.
# Create a DexiDiscretizeFunction (without association to any attributes or scales) fnc <- DexiDiscretizeFunction(bounds = c(-1, 2), values = list(1, 3, 5), assoc = c("up", "down")) # Print fields and basic properties of fnc fnc$verify() fnc$nargs() fnc$nvals() fnc$to_string() fnc$bound_assoc(1) fnc$bound_assoc(2) # Try some discretizations sapply(c(-1.1, -1, 0, 1, 2, 3), fnc$evaluate)
# Create a DexiDiscretizeFunction (without association to any attributes or scales) fnc <- DexiDiscretizeFunction(bounds = c(-1, 2), values = list(1, 3, 5), assoc = c("up", "down")) # Print fields and basic properties of fnc fnc$verify() fnc$nargs() fnc$nvals() fnc$to_string() fnc$bound_assoc(1) fnc$bound_assoc(2) # Try some discretizations sapply(c(-1.1, -1, 0, 1, 2, 3), fnc$evaluate)
DexiFunction
is a base RC class for representing DEXi aggregation and discretization functions in R.
DEXi functions are generally associated with aggregate attributes. For some aggregate attribute att
,
att$funct
defines the mapping from values of att$inputs
to values of att
.
DexiFunction is a base class that defines fields and methods common to all functions:
method value(x)
: returns the function value for arguments x
. Arguments are
assumed to be a numeric vector of length equal to att$inputs
.
method evaluate(x)
is a silent wrapper around value(x)
; it returns NULL
when
value(x)
fails with an error.
DEXiR implements two other function classes derived from DexiFunction
:
DexiTabularFunction and DexiDiscretizeFunction.
evaluate(x)
A silent wrapper around value(x)
; it returns NULL
when
value(x)
fails with an error.
value(x)
Return the function value for arguments x
, where arguments are
a numeric vector of length equal to att$inputs
.
Additionally, arguments of a DexiTabularFunctions$value()
must be integer numbers,
and the argument of DexiDiscretizeFunctions$value()
must be a single number.
verify()
Check the correctnes of this function object and its fields.
Result: error()
or TRUE
.
DexiModel
is a RC class representing a DEXi model in R.
Normally, DexiModel
objects are created by reading from a .dxi
file,
previously developed by the DEXi software. In principle, all fields of a DexiModel
should be considered read-only. DEXiR does not provide any explicit
functionality for creating and changing DEXi models in R. Of course, models can still be created
and modified in R, but without integrity and consistency guarantees.
name
character. Name of the model.
description
character. An optional textual description of the model.
linking
logical. Indicates whether or not the model uses linked attributes, which are used in DEXi to represent hierarchies of attributes (i.e., directed acyclic graphs) rather than trees.
root
DexiAttribute. The virtual root of all subtrees/hierarchies of attributes in the model.
attributes
list. A list of all DexiAttributes that constitute the model.
att_names
character. A list of all attribute names, as defined in the original DEXi model. Notice that these names may contain whitespace and other "strange" characters, and may not be unique.
att_ids
character. A list of unique attribute IDs generated by DEXiR from att_names
using make.unique
. When using the DEXiR package, it is strongly advised to refer to
attributes with their IDs rather than DEXi names.
basic
list. A list of all basic (input) DexiAttributes in the model.
aggregate
list. A list of all aggregate (output) DexiAttributes in the model.
links
list. A list of all linked DexiAttributes in the model.
basic_ids
character. A vector of all basic attributes' unique names.
aggregate_ids
character. A vector of all aggregate attributes' unique names.
link_ids
character. A vector of all linked attributes' unique names.
alternatives
data.frame. A data frame representing decision alternatives contained
in the .dxi
file.
alternative(name = "NewAlternative", ...)
Create a data frame containing data of one decision alternative.
name
, character(1), represents the alternative's name. The arguments ...
define the alternative's values to be put in the data frame.
Please see set_alternative
for the syntax of ...
.
as_character(alt, transpose = FALSE, structure = FALSE, round = NULL)
The argument alt
is assumed to be a data frame containing data of one or more decision alternatives
with values represented by numeric vectors. as_character(alt)
transforms the values of
alt
into a more human-readable form using character strings.
Additionally, transpose = TRUE
transposes the data frame,
so that rows correspod to attributes and columns to alternatives.
structure = TRUE
additionally displays the tree structure of attributes;
the latter works only with transpose = TRUE
.
round
denotes the number of decimal digits for printing numeric values.
att_index(atts, use_id = TRUE)
Find the indices of attributes.
atts
is a character vector of attribute IDs (when use_id = TRUE
) or original DEXi attribute
names (when use_id = FALSE
). Result: a numeric vector containing the set of indices.
Example: Car$att_index(c("PRICE", "TECH.CHAR."))
att_stat()
Count the number of all attributes (including the virtual root), as well as the number of basic, aggregate and linked attributes in the model. Result: a list of the form list(all=..., basic=..., aggregate=..., link=...).
attrib(atts)
A general function for finding attributes in the model. atts
is a vector or list of
DexiAttribute
s, attribute indices (integer) or attribute IDs (character).
Result: a list of found DexiAttribute
s (or NA
s if not found).
Example: Car$attrib(list(5, "PRICE", "TECH.CHAR."))
compare_alternatives(...)
Calls compare_alternatives(.self, ...)
to carry out Comparison of Alternatives.
Please see compare_alternatives
for the description of ...
arguments.
convert(...)
Calls convert_alternatives(.self, ...)
to convert decision alternatives' data.
Please see convert_alternatives
for the description of ...
arguments.
evaluate(...)
Calls evaluate(.self, ...)
to evaluate decision alternatives.
Please see evaluate
for the description of ...
arguments.
first()
Return first non-virtual model attribute, i.e., first descendant of model$root.
initialize(name = "", description = "", root = NULL, linking = FALSE, ...)
Initialize a DexiModel
object.
link_attributes()
Carries out the linking of attributes.
DEXi attributes that have the same names and value scales,
and satisfy some other constraints to prevent making cycles in the model,
are linked together so that they logically represent a single attribute.
In this way, a tree of attributes is conceptually turned in a hierarchy (directed acyclic graph).
If linking = TRUE
, link_attributes
is called by setup()
after reading the model.
plus_minus(...)
Calls plus_minus(.self, ...)
to carry out Plus-Minus Analysis.
Please see plus_minus
for the description of ...
arguments.
scale(atts)
Find attribute scales. atts
is a vector of DexiAttribute
s.
Result: a vector of the corresponding DexiScale
s (or NA
s).
selective_explanation(...)
Calls selective_explanation(.self, ...)
to carry out Selective Explanation.
Please see selective_explanation
for the description of ...
arguments.
setup()
Called by initialize()
as the last step that establishes consistent internal data structures by
making unique attribute IDs, linking attributes (if required), making lists of attributes and their IDs,
and creating a data frame of alternatives.
verify()
Check the correctnes of a DexiModel
object and its fields. Result: error()
or TRUE
.
evaluate
, set_alternative
, read_dexi()
# Get ".dxi" file name CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") # Read DEXi model Car <- read_dexi(CarDxi) # Print fields of Car Car Car$verify() Car$name Car$description Car$linking att_names(Car$attributes) Car$att_names Car$att_ids Car$basic_ids Car$aggregate_ids Car$att_stat() Car$scale(Car$aggregate) # Find some attributes in the model Car$first() Car$attributes[[3]] Car$attrib("PRICE") Car$att_index("PRICE") # Display alternatives loaded from "Car.dxi" Car$alternatives Car$as_character(Car$alternatives) Car$as_character(Car$alternatives, transpose = TRUE) Car$as_character(Car$alternatives, transpose = TRUE, structure = TRUE) # Define and evaluate a decision alternative (some car) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS=3, X.DOORS=3, LUGGAGE="medium", SAFETY=2) Car$evaluate(alt) Car$as_character(Car$evaluate(alt)) # Employ the set-based evaluation (notice how the value of SAFETY propagates upwards to TECH.CHAR.) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS=3, X.DOORS=3, LUGGAGE="medium", SAFETY=c(2,3)) Car$evaluate(alt) Car$as_character(Car$evaluate(alt)) # Analysis of alternatives Car$selective_explanation(1) Car$selective_explanation(alt) Car$plus_minus(alt) Car$compare_alternatives(alt) Car$compare_alternatives(1, 2) Car$compare_alternatives(1, alt)
# Get ".dxi" file name CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") # Read DEXi model Car <- read_dexi(CarDxi) # Print fields of Car Car Car$verify() Car$name Car$description Car$linking att_names(Car$attributes) Car$att_names Car$att_ids Car$basic_ids Car$aggregate_ids Car$att_stat() Car$scale(Car$aggregate) # Find some attributes in the model Car$first() Car$attributes[[3]] Car$attrib("PRICE") Car$att_index("PRICE") # Display alternatives loaded from "Car.dxi" Car$alternatives Car$as_character(Car$alternatives) Car$as_character(Car$alternatives, transpose = TRUE) Car$as_character(Car$alternatives, transpose = TRUE, structure = TRUE) # Define and evaluate a decision alternative (some car) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS=3, X.DOORS=3, LUGGAGE="medium", SAFETY=2) Car$evaluate(alt) Car$as_character(Car$evaluate(alt)) # Employ the set-based evaluation (notice how the value of SAFETY propagates upwards to TECH.CHAR.) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS=3, X.DOORS=3, LUGGAGE="medium", SAFETY=c(2,3)) Car$evaluate(alt) Car$as_character(Car$evaluate(alt)) # Analysis of alternatives Car$selective_explanation(1) Car$selective_explanation(alt) Car$plus_minus(alt) Car$compare_alternatives(alt) Car$compare_alternatives(1, 2) Car$compare_alternatives(1, alt)
DexiScale
is a base RC class representing value scales in R.
A value scale defines the type and set of values that can be assigned to some DexiAttribute. DexiScale is a base scale class that defines fields and methods common to all scales:
whether or not the scale is preferentially ordered (and in which direction),
scale type (discrete or continuous),
the number of scale elements, if countable,
partition of scale elements in three preferential classes: "bad"
, "good"
and "none"
,
helper methods value_index()
and full_range()
.
DEXiR implements two other scale classes derived from DexiScale
:
DexiContinuousScale and DexiDiscreteScale.
order
character. Preferential order of the scale.
Possible values: "ascending"
, "descending"
or "none"
.
count()
Return the number of scale elements.
Equal to NA
for DexiScale
, 0
for DexiContinuousScale
, and
equal to nvals >= 0
for DexiDiscreteScale
.
equal(scl)
Check if this scale is equal to scale scl
. Needed for attribute linking.
full_range()
Return the vector that represents the full range of values on this scale.
Equal to NA
for DexiScale
and DexiContinuousScale
,
and 1 : scale$nvals
for DexiDiscreteScale
.
initialize(order = EnumOrder, ...)
Initialize a DexiScale
object.
is_continuous()
Logical: Is this scale continuos?
is_discrete()
Logical: Is this scale discrete?
to_string()
Return a string representation of this scale for printing.
value_index(value)
Find the index of value
(character(1)) on this scale.
Equal to NA
for DexiScale
and DexiContinuousScale
.
With DexiDiscreteScale
objects, it returns a numeric index or NA
of value
in scale$values
.
value_quality(value)
Return the quality (preferential class) of value
on this scale:
one of the strings "bad"
, "none"
or "good"
.
Always "none"
for DexiScale
and scales with order = "none"
.
verify()
Check the correctnes of this scale object and its fields.
Result: error()
or TRUE
.
DexiTabularFunction
is a RC class, derived from DexiFunction.
Functions of this type aggregate attribute values according to decision rules,
defined in terms of a decision table.
A decision table contains as many decision rules as there are possible combinations of
input attributes' values. For instance, if some attribute
has two inputs whose
discrete scales have three and four values, respectively (i.e., attribute$dim() == c(3,4)
),
then the number of rules is equal to prod(attribute$dim()) == 12
. Each rule defines the
value of attribute
for one of the possible combinations of values of attribute$inputs
.
Thus, a decision table can be interpreted as a lookup table that, given a vector
of values of attribute$inputs
(i.e., function arguments) returns the corresponding
attribute
value.
Objects of class DexiTabularFunction
store decision rules in values
, a multi-dimensional
list that contains rule values. In most cases, a rule value is a single integer,
representing an ordinal number of some value from attribute$scale
. In a general case, however,
a rule value can be an integer vector, representing a (sub)set of values from attribute$scale
.
attribute
DexiAttribute. The attribute this function is associated with.
Both the attribute and its inputs are required to be discrete (i.e., associated with
DexiDiscreteScale
s).
values
A multi-dimensional list of rule values. The dimensions of the list are equal to
attribute$dim()
, and the length of the list is nvals() == prod(dim)
. The list
contains rule values that are in general value sets, i.e., integer vectors of value indices
w.r.t. attribute$scale
.
args
A list of integer vectors, containing all possible combinations of values of attribute$inputs
.
args
and values
are of the same length and ordered so that, for each i
, args[[i]]
defines function arguments that map to values[[i]]
).
evaluate(x)
A silent wrapper around value(x)
; it returns NULL
when
value(x)
fails with an error.
nargs()
Return the number of function arguments.
nvals()
Return the function size (number of rules).
to_string()
Return a short informative string about the size and dimensions of values
.
value(x)
Return the function value for arguments x
, where arguments are
a numeric vector of length equal to att$inputs
.
Additionally, arguments of a DexiTabularFunctions$value()
must be integer numbers,
and the argument of DexiDiscretizeFunctions$value()
must be a single number.
verify()
Check the correctnes of this function object and its fields.
Result: error()
or TRUE
.
dexi_index()
, dexi_table()
, make_args()
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # For example, consider the function of attribute CAR fnc <- Car$attrib("CAR")$funct # Print fields and basic properties of fnc fnc$verify() att_names(fnc$attribute) fnc$values fnc$args fnc$nargs() fnc$nvals() fnc$to_string() # Try some args to value mappings fnc$evaluate(c(1, 1)) fnc$evaluate(c(2, 2)) fnc$evaluate(c(3, 4)) fnc$evaluate(c(4, 4)) # the first argument is out of bounds, returns NULL
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # For example, consider the function of attribute CAR fnc <- Car$attrib("CAR")$funct # Print fields and basic properties of fnc fnc$verify() att_names(fnc$attribute) fnc$values fnc$args fnc$nargs() fnc$nvals() fnc$to_string() # Try some args to value mappings fnc$evaluate(c(1, 1)) fnc$evaluate(c(2, 2)) fnc$evaluate(c(3, 4)) fnc$evaluate(c(4, 4)) # the first argument is out of bounds, returns NULL
Convert a DEXi value distribution to a DEXi value set.
distr_to_set(distr, eps = .Machine$double.eps)
distr_to_set(distr, eps = .Machine$double.eps)
distr |
An S3 object of class |
eps |
A numeric value representing the threshold value of |
A numeric vector determined as which(distr > eps)
. Notice that distr_to_set
is generally a lossy conversion, so that multiple different distr
s are converted to the same sets.
DEXiR-package, distribution, set_to_distr()
distr_to_set(distribution(0.2, 0, 0.5, 0.3)) distr_to_set(distribution(0.1, 0, 0.7, 0.2)) distr_to_set(distribution(0.1, 0, 0.7, 0.2), eps = 0.5)
distr_to_set(distribution(0.2, 0, 0.5, 0.3)) distr_to_set(distribution(0.1, 0, 0.7, 0.2)) distr_to_set(distribution(0.1, 0, 0.7, 0.2), eps = 0.5)
Create an object as a S3 class distribution
.
distribution(...)
distribution(...)
... |
Expected a comma-separated list of numeric values. |
An object, call it obj
, such that all(obj == c(...))
and
class(obj) == "distribution"
.
DEXiR-package, set_to_distr()
, distr_to_set()
distribution(0.1, 0.2, 0.7)
distribution(0.1, 0.2, 0.7)
Check if two scales are equal. NULL
arguments, indicating undefined scales, are allowed.
Two NULL
scales are considered equal.
equal_scales(scl1, scl2)
equal_scales(scl1, scl2)
scl1 |
A DexiScale (or derived) object, or |
scl2 |
A DexiScale (or derived) object, or |
logical(1)
.
Evaluates decision alternatives. Essentially, this is a bottom-up aggregation method:
starting with basic attributes (or prune
d aggregate attributes), values of each
alternative are gradually aggregated towards the root
attribute,
according to evaluation_order()
. The aggregation
at each individual DexiAttribute is governed by the corresponding DexiAttribute$funct
.
When alternative values are sets or distributions (see DEXiR-package),
then evaluate()
tries all possible combinations of values of the descendant attributes.
evaluate( model, alternatives = model$alternatives, root = model$root, method = EnumEvalMethod, bounding = FALSE, prune = list(), norm = NULL, and = NULL, or = NULL )
evaluate( model, alternatives = model$alternatives, root = model$root, method = EnumEvalMethod, bounding = FALSE, prune = list(), norm = NULL, and = NULL, or = NULL )
model |
|
alternatives |
A data frame containing data of one or more decision alternatives. |
root |
DexiAttribute. Default: |
method |
One of: |
bounding |
|
prune |
|
norm |
Some normalization function of the form |
and |
Some conjunctive aggregation function of the form |
or |
Some disjunctive aggregation function of the form |
evaluate()
implements four aggregation methods:
"set"
, "prob"
, "fuzzy"
and "fuzzynorm"
.
The "set"
method interprets DEXi values as sets. The output value assigned to some attribute
is
composed of the union of all attribute$funct
evaluations for all possible combinations of values of
attribute$inputs
.
The remaining three methods interpret DEXi values as value distributions. They follow the same algorithm,
but use different functions (see evaluation_parameters()
) in three algorithm steps:
normalization, and conjunctive and disjunctive aggregation. All values distributions involved in
calculations are normalized by the function norm()
. All combinations of attribute$input
values are individually evaluated by the corresponding tabular function attribute$funct
.
The value of each set of
attribute$funct
arguments is determined by the conjunctive
aggregation function and()
over 's of individual arguments.
Finally, the
of some output value
val
is determined by the
disjunctive aggregation function or()
, applied on the 's of all partial evaluations that
map to
val
.
For the mathematical background and more details about aggregation in DEX, please see
(Trdin, Bohanec, 2018). For default normalization and aggregation functions,
see normalize_function()
, and_function()
and or_function()
.
A data frame containing both input and output (evaluated) values of alternatives
.
evaluation_parameters()
, normalize_function()
,
norm_none()
, norm_max()
, norm_sum()
, and_function()
, or_function()
, bounded_scale_value()
.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar_set", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") Car$evaluate(alt) # Try the set-based evaluation using the default "set" method alt <- Car$alternative("MyCar2", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=2) Car$evaluate(alt) # Use value distributions and try the methods "prob", "fuzzy" and "fuzzynorm" alt <- Car$alternative("MyCar_distr", BUY.PRICE="low", MAINT.PRICE=distribution(0.1, 0.6, 0.3), X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=2) Car$evaluate(alt, method = "prob") Car$evaluate(alt, method = "fuzzy") Car$evaluate(alt, method = "fuzzynorm")
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar_set", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") Car$evaluate(alt) # Try the set-based evaluation using the default "set" method alt <- Car$alternative("MyCar2", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=2) Car$evaluate(alt) # Use value distributions and try the methods "prob", "fuzzy" and "fuzzynorm" alt <- Car$alternative("MyCar_distr", BUY.PRICE="low", MAINT.PRICE=distribution(0.1, 0.6, 0.3), X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=2) Car$evaluate(alt, method = "prob") Car$evaluate(alt, method = "fuzzy") Car$evaluate(alt, method = "fuzzynorm")
Evaluate alternative
for a sequence of attribute
values.
evaluate_attribute(model, attribute, alternative, seq = NULL, ...)
evaluate_attribute(model, attribute, alternative, seq = NULL, ...)
model |
A DexiModel. |
attribute |
A DexiAttribute with an assigned discrete or continuous scale. |
alternative |
A |
seq |
A sequence of |
... |
Optional parameters passed to |
A list of evaluated alternatives for consecutive attribute
values from seq
.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") safety <- Car$attrib("SAFETY") # Evaluate alt for all values of att evaluate_attribute(Car, safety, alt) # Returns a list of three alternatives for values SAFETY=c("small", "medium", "high")
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") safety <- Car$attrib("SAFETY") # Evaluate alt for all values of att evaluate_attribute(Car, safety, alt) # Returns a list of three alternatives for values SAFETY=c("small", "medium", "high")
Apply evaluate_attribute()
for all discrete attributes
.
evaluate_attributes(model, alternative, attributes = NULL, ...)
evaluate_attributes(model, alternative, attributes = NULL, ...)
model |
A DexiModel object. Required. |
alternative |
A |
attributes |
List of attributes or vector of attribute names, ID's or indices.
Default: All basic attributes of |
... |
Optional parameters passed to |
A list of evaluate_attribute()
results for each attribute
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") safety <- Car$attrib("SAFETY") # Perform evaluate_attribute() for all basic attributes of CarDxi evaluate_attributes(Car, alt) # Returns a list of evaluate_attribute() results corresponding to all basic attributes, # indexed by attribute id
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE=2, X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY="medium") safety <- Car$attrib("SAFETY") # Perform evaluate_attribute() for all basic attributes of CarDxi evaluate_attributes(Car, alt) # Returns a list of evaluate_attribute() results corresponding to all basic attributes, # indexed by attribute id
Determine the evaluation order of attributes. Interpreted as a sequence, the order guarantees that whenever some attribute is reached as a candidate for evaluation, all the previous attributes have been already evaluated.
evaluation_order(att, prune = list())
evaluation_order(att, prune = list())
att |
DexiAttribute. The starting point of evaluation. |
prune |
A character vector. May contain IDs of aggregate attributes at which the evaluation should stop, treating them as if they were basic attributes. |
A character vector of attribute IDs.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Full evaluation order, starting with Car$root and without pruning evaluation_order(Car$root) # Evaluation order, starting with the TECH.CHAR. attribute evaluation_order(Car$attrib("TECH.CHAR.")) # evaluation order, starting with Car$root and pruned at "PRICE" evaluation_order(Car$root, prune = "PRICE")
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Full evaluation order, starting with Car$root and without pruning evaluation_order(Car$root) # Evaluation order, starting with the TECH.CHAR. attribute evaluation_order(Car$attrib("TECH.CHAR.")) # evaluation order, starting with Car$root and pruned at "PRICE" evaluation_order(Car$root, prune = "PRICE")
Make a list containing parameters of DEXi evaluation. The parameters determine which method
and normalization/aggregation functions should be used by evaluate()
.
evaluation_parameters( method = EnumEvalMethod, norm = NULL, and = NULL, or = NULL )
evaluation_parameters( method = EnumEvalMethod, norm = NULL, and = NULL, or = NULL )
method |
One of: |
norm |
Some normalization function of the form |
and |
Some conjunctive aggregation function of the form |
or |
Some disjunctive aggregation function of the form |
list(method, norm, and, or)
.
For NULL
norm
, and
, and or
arguments, defaults are
taken depending on the method
.
evaluate, normalize_function()
,
norm_none()
, norm_max()
, norm_sum()
, and_function()
, or_function()
.
evaluation_parameters("prob", norm = norm_none)
evaluation_parameters("prob", norm = norm_none)
Expand a DEXi value
to a sequence of individual elements (points).
Particularly aimed for graphic functions that display DEXi values
with dots of different sizes and colors.
expand_value_to_points(value, scale, colors = c("red", "black", "green"))
expand_value_to_points(value, scale, colors = c("red", "black", "green"))
value |
A DEXi value: a single value (integer or float), a set (integer vector) or a distribution. |
scale |
A DexiScale object. |
colors |
|
A data.frame
consisting of:
points
numeric()
. value
expanded to a vector of ordinal values.
sizes
numeric()
. Numeric values assigned to each corresponding ordinal values.
Normally 1.0
for set elements and in the (0,1]
interval for distribution membership values.
colors
Colors assigned to corresponding value qualities.
scl <- DexiDiscreteScale(values = c("L", "M", "H")) expand_value_to_points(c(1, 3), scl) # points sizes colors # 1 1 1 red # 2 3 1 green expand_value_to_points(distribution(0.1, 0, 0.9), scl) # points sizes colors # 1 1 0.1 red # 2 3 0.9 green
scl <- DexiDiscreteScale(values = c("L", "M", "H")) expand_value_to_points(c(1, 3), scl) # points sizes colors # 1 1 1 red # 2 3 1 green expand_value_to_points(distribution(0.1, 0, 0.9), scl) # points sizes colors # 1 1 0.1 red # 2 3 0.9 green
Convert alternatives
' data to a data frame formatted so that it can be
imported by DEXi/DEXiWin software.
export_alternatives(model, alternatives = NULL)
export_alternatives(model, alternatives = NULL)
model |
A DexiModel object. Required. |
alternatives |
A |
In order to import the output of export_alternative()
in DEXi/DEXiWin software,
proper Import/Export
settings must be ensured in these programs:
Option values: "base 1", Attributes: "all", Orientation: "normal", Indent: "indent".
Option values: "Base 1", Attributes: "All",
Orientation: "Attributes \ Alternatives",
Indent: "Indent tree levels",
CSV Format: "Invariant" when format = "csv"
and "Local" when format = "csv2"
.
If alternatives
contain value distributions,
they can be imported only by DEXiWin and not by DEXi.
A data frame consisting of character strings that can be further written out by write_alternatives()
.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) export_alternatives(Car) # export both alternatives from Car export_alternatives(Car, 1) # export only the first alternative
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) export_alternatives(Car) # export both alternatives from Car export_alternatives(Car, 1) # export only the first alternative
Convert a DEXi value
to a character string that is understood by DEXi/DEXiWin software
while importing data about alternatives.
export_dexi_value(value)
export_dexi_value(value)
value |
A DEXi value: |
A string representation of value
.
export_dexi_value(NULL) # "<undefined>" export_dexi_value(NA) # "<undefined>" export_dexi_value(1) # "1" export_dexi_value(3.2) # "3.2" export_dexi_value(c(1, 3, 5)) # "1;3;5" export_dexi_value(distribution(0.1, 0.9)) # "1/0.1;2/0.9" export_dexi_value(distribution(0, 0.1, 0, 0.9, 0)) # "2/0.1;4/0.9"
export_dexi_value(NULL) # "<undefined>" export_dexi_value(NA) # "<undefined>" export_dexi_value(1) # "1" export_dexi_value(3.2) # "3.2" export_dexi_value(c(1, 3, 5)) # "1;3;5" export_dexi_value(distribution(0.1, 0.9)) # "1/0.1;2/0.9" export_dexi_value(distribution(0, 0.1, 0, 0.9, 0)) # "2/0.1;4/0.9"
"Flatten" the function argument using c(value)
, concatenate the elements and separate them by
a single space.
flat_text(value)
flat_text(value)
value |
Any object that can occur as an argument of |
character(1)
.
Makes a basic ggplot2
chart for displaying DEXi alternatives using parallel axes.
Generally, axes are uniformly scaled to the [0,1]
interval.
ggplot_parallel( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01 )
ggplot_parallel( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01 )
model |
A DexiModel object. Required. |
alternatives |
A |
attids |
|
aggregate |
One of |
name |
|
shift |
|
Uses GGally::ggparcoord()
and requires package "GGally" to be installed.
Data presented in the chart is prepared by scale_alternatives()
.
A basic 'ggplot2' chart. Generally, this chart needs to be further enhanced
by graph layers, such as themes, labels, geom_points()
and geom_line()
.
See plotalt_parallel()
that already provides some such layers.
scale_alternatives()
, plotalt_parallel()
if (requireNamespace("GGally", quietly = TRUE)) { # Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with points and lines ggplot_parallel(Car) + ggplot2::geom_line(linewidth = 2) + ggplot2::geom_point(size = 3) }
if (requireNamespace("GGally", quietly = TRUE)) { # Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with points and lines ggplot_parallel(Car) + ggplot2::geom_line(linewidth = 2) + ggplot2::geom_point(size = 3) }
has_quality
has_quality(quality = EnumQuality, value, scale)
has_quality(quality = EnumQuality, value, scale)
quality |
A character string from |
value |
A DEXi value. |
scale |
A DexiScale or derived object. |
logical(1)
. Whether or not value_qualities(value, scale)
contains quality
.
Checks whether value
is of DexDistributionClass
or not.
is_distribution(value)
is_distribution(value)
value |
Any value or object to be checked. |
logical(1)
. Returns TRUE
if value
is distribution.
is_distribution(NULL) is_distribution(3) is_distribution("text") is_distribution(c(1,2,3)) is_distribution(distribution(1,0,2))
is_distribution(NULL) is_distribution(3) is_distribution("text") is_distribution(c(1,2,3)) is_distribution(distribution(1,0,2))
Check whether or not x
lies the specified range.
is_in_range(x, lb, hb, lassoc = c("up", "down"), hassoc = c("down", "up"))
is_in_range(x, lb, hb, lassoc = c("up", "down"), hassoc = c("down", "up"))
x |
Any object type, but using a non-numeric argument always returns |
lb |
|
hb |
|
lassoc |
|
hassoc |
|
logical(1)
, indicating whether or not x
lies in the interval [lb:hb]
according to function arguments.
is_in_range(3, 2, 5) is_in_range(7, 2, 5) is_in_range(3, 3, 5) is_in_range(3, 3, 5, lassoc = "down")
is_in_range(3, 2, 5) is_in_range(7, 2, 5) is_in_range(3, 3, 5) is_in_range(3, 3, 5, lassoc = "down")
Map value x
linearly from interval [imin:imax]
to [omax:omax]
.
lin_map(x, imin, imax, omin = 0, omax = 1)
lin_map(x, imin, imax, omin = 0, omax = 1)
x |
|
imin |
|
imax |
|
omin |
|
omax |
|
numeric()
. Mapped value(s).
lin_map(2, 1, 3) # 0.5
lin_map(2, 1, 3) # 0.5
Make a list of all possible combinations of values in a decision space defined by dim
.
make_args(dim)
make_args(dim)
dim |
A numeric vector containing upper bounds of the corresponding decision space dimensions.
For example, |
A list containing all possible value combinations. List elements are numeric vectors
of length equal to length(dim)
.
make_args(c(3, 4))
make_args(c(3, 4))
Normalize values
so that max(values) == max
.
norm_max(values, max = 1)
norm_max(values, max = 1)
values |
A numeric vector. |
max |
|
values
normalized so that max(result) == max
.
Returns unchanged values
when max(values) == 0
.
norm_max(c(0, 0.5, 0.7))
norm_max(c(0, 0.5, 0.7))
A "do nothing" normalization function.
norm_none(values)
norm_none(values)
values |
A numeric vector. |
Returns unchanged values
.
norm_none(c(0, 0.5, 0.7))
norm_none(c(0, 0.5, 0.7))
Normalize values
so that sum(values) == sum
.
norm_sum(values, sum = 1)
norm_sum(values, sum = 1)
values |
A numeric vector. |
sum |
|
values
normalized so that sum(result) == sum
.
Returns unchanged values
when sum(values) == 0
norm_sum(c(0, 0.5, 0.7))
norm_sum(c(0, 0.5, 0.7))
Determine the function to be used in the normalization step of evaluate()
.
normalize_function(method = EnumEvalMethod, norm = NULL)
normalize_function(method = EnumEvalMethod, norm = NULL)
method |
One of: |
norm |
Some normalization function of the form |
Returns function norm
if not NULL
.
Otherwise, it determines the result depending on method
:
"set"
:"prob"
:"fuzzy"
:"fuzzynorm"
:Fails with an error if the result is not an R function.
evaluate
, norm_none()
, norm_max()
, norm_sum()
,
Determine the function to be used in the disjunctive aggregation step of evaluate()
.
or_function(method = EnumEvalMethod, or = NULL)
or_function(method = EnumEvalMethod, or = NULL)
method |
One of: |
or |
Some disjunctive aggregation function of the form |
Returns the function or
if not NULL
.
Otherwise, it determines the result depending on method
:
Fails with an error if the result is not an R function.
Makes and plots DEXi alternatives on parallel axes, corresponding to attributes.
Generally, axes are uniformly scaled to the [0,1]
interval.
plotalt_parallel( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01, linewidth = 2, pointsize = 3, split = c("no", "h", "v") )
plotalt_parallel( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01, linewidth = 2, pointsize = 3, split = c("no", "h", "v") )
model |
A DexiModel object. Required. |
alternatives |
A |
attids |
|
aggregate |
One of |
name |
|
shift |
|
linewidth |
|
pointsize |
|
split |
One of:
|
Data presented in the chart is prepared by scale_alternatives()
.
plotalt_parallel()
invokes ggplot_parallel()
to make a basic chart and then
enhances it with graphic layers that are suitable for presenting DEXi alternatives.
A 'ggplot2' chart, enhanced with additional graph layers.
scale_alternatives()
, ggplot_parallel()
if (requireNamespace("GGally", quietly = TRUE)) { # Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with points and lines plotalt_parallel(Car) # Show alternatives on two separate chart segments, shown one above the other. plotalt_parallel(Car, split = "v") alts3 <- structure( list( name = c("MyCar", "MyCar2", "MyCar1b"), CAR.1 = list(4L, 4L, c(1L, 4L)), PRICE = list(3L, 3L, c(1L, 3L)), BUY.PRICE = list(3L, 3L, 3L), MAINT.PRICE = list(2, 1, structure(c(0.1, 0.6, 0.3), class = "distribution")), TECH.CHAR. = list(3L, 3:4, 3L), COMFORT = list(3L, 2, 3L), X.PERS = list(3, 3, 3L), X.DOORS = list(3, 3, 3L), LUGGAGE = list(2L, 2L, 2), SAFETY = list(2, c(2, 3), 2) ), row.names = c(NA, -3L), class = "data.frame" ) # Plot `alts2` with points and lines. # Notice the "minmax" aggregation of sets and distributions. plotalt_parallel(Car, alts3) plotalt_parallel(Car, alts3, split = "v") # Now with "mean" aggregation plotalt_parallel(Car, alts3, split = "v", aggregate = "mean") }
if (requireNamespace("GGally", quietly = TRUE)) { # Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with points and lines plotalt_parallel(Car) # Show alternatives on two separate chart segments, shown one above the other. plotalt_parallel(Car, split = "v") alts3 <- structure( list( name = c("MyCar", "MyCar2", "MyCar1b"), CAR.1 = list(4L, 4L, c(1L, 4L)), PRICE = list(3L, 3L, c(1L, 3L)), BUY.PRICE = list(3L, 3L, 3L), MAINT.PRICE = list(2, 1, structure(c(0.1, 0.6, 0.3), class = "distribution")), TECH.CHAR. = list(3L, 3:4, 3L), COMFORT = list(3L, 2, 3L), X.PERS = list(3, 3, 3L), X.DOORS = list(3, 3, 3L), LUGGAGE = list(2L, 2L, 2), SAFETY = list(2, c(2, 3), 2) ), row.names = c(NA, -3L), class = "data.frame" ) # Plot `alts2` with points and lines. # Notice the "minmax" aggregation of sets and distributions. plotalt_parallel(Car, alts3) plotalt_parallel(Car, alts3, split = "v") # Now with "mean" aggregation plotalt_parallel(Car, alts3, split = "v", aggregate = "mean") }
Plots DEXi alternatives on a radar chart.
Generally, axes are uniformly scaled to the [0,1]
interval.
plotalt_radar( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01, linewidth = 2, ptype = 16, colors = NULL, unicolors = NULL, fillcolors = NULL, transparency = 85, circular = FALSE, split = FALSE, fill = FALSE, ... )
plotalt_radar( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01, linewidth = 2, ptype = 16, colors = NULL, unicolors = NULL, fillcolors = NULL, transparency = 85, circular = FALSE, split = FALSE, fill = FALSE, ... )
model |
A DexiModel object. Required. |
alternatives |
A |
attids |
|
aggregate |
One of |
name |
|
shift |
|
linewidth |
|
ptype |
A vector to specify point symbol: Default |
colors |
Colors to be used (repeatably) for data series. Default |
unicolors |
A vector of one or two colors to be used for displaying the
minimum and maximum data series, respectively. Applies only when |
fillcolors |
A vector of color codes for filling polygons. Applies only when |
transparency |
A number between |
circular |
|
split |
|
fill |
|
... |
Optional parameters passed to |
Uses fmsb::radarchart()
and requires package "fmsb" to be installed.
Data presented in the chart is prepared by scale_alternatives()
.
Draws a chart or, when split = TRUE
a series of charts corresponding to individual alternatives.
scale_alternatives()
, fmsb::radarchart()
if (requireNamespace("fmsb", quietly = TRUE)) { # Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with points and lines plotalt_radar(Car) # Use different colors and fill polygons plotalt_radar(Car, colors = c("blue", "brown"), fill = TRUE) plotalt_radar(Car, colors = c("blue", "brown"), fillcolors = c("green", "red"), fill = TRUE) # Draw separate charts plotalt_radar(Car, split = TRUE) # Draw separate charts, using the same color settings on all charts plotalt_radar(Car, split = TRUE, unicolors = c("green", "red")) plotalt_radar(Car, split = TRUE, unicolors = c("green", "red"), circular = TRUE) alts3 <- structure( list( name = c("MyCar", "MyCar2", "MyCar1b"), CAR.1 = list(4L, 4L, c(1L, 4L)), PRICE = list(3L, 3L, c(1L, 3L)), BUY.PRICE = list(3L, 3L, 3L), MAINT.PRICE = list(2, 1, structure(c(0.1, 0.6, 0.3), class = "distribution")), TECH.CHAR. = list(3L, 3:4, 3L), COMFORT = list(3L, 2, 3L), X.PERS = list(3, 3, 3L), X.DOORS = list(3, 3, 3L), LUGGAGE = list(2L, 2L, 2), SAFETY = list(2, c(2, 3), 2) ), row.names = c(NA, -3L), class = "data.frame" ) # The same chart types as above, but using more varied alternatives data # Plot all Car$alternatives with points and lines plotalt_radar(Car, alts3) # Use different colors and fill polygons plotalt_radar(Car, alts3, colors = c("blue", "brown", "purple"), fill = TRUE) plotalt_radar(Car, alts3, colors = c("blue", "brown", "purple"), fillcolors = c("green", "red", "yellow"), fill = TRUE) # Draw separate charts plotalt_radar(Car, alts3, split = TRUE) plotalt_radar(Car, alts3, split = TRUE, fill = TRUE) # Draw separate charts, using the same color settings on all charts plotalt_radar(Car, alts3, split = TRUE, unicolors = c("red", "green")) plotalt_radar(Car, alts3, split = TRUE, unicolors = c("green", "darkgreen"), fill = TRUE) plotalt_radar(Car, alts3, split = TRUE, unicolors = c("red", "green"), circular = TRUE) }
if (requireNamespace("fmsb", quietly = TRUE)) { # Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with points and lines plotalt_radar(Car) # Use different colors and fill polygons plotalt_radar(Car, colors = c("blue", "brown"), fill = TRUE) plotalt_radar(Car, colors = c("blue", "brown"), fillcolors = c("green", "red"), fill = TRUE) # Draw separate charts plotalt_radar(Car, split = TRUE) # Draw separate charts, using the same color settings on all charts plotalt_radar(Car, split = TRUE, unicolors = c("green", "red")) plotalt_radar(Car, split = TRUE, unicolors = c("green", "red"), circular = TRUE) alts3 <- structure( list( name = c("MyCar", "MyCar2", "MyCar1b"), CAR.1 = list(4L, 4L, c(1L, 4L)), PRICE = list(3L, 3L, c(1L, 3L)), BUY.PRICE = list(3L, 3L, 3L), MAINT.PRICE = list(2, 1, structure(c(0.1, 0.6, 0.3), class = "distribution")), TECH.CHAR. = list(3L, 3:4, 3L), COMFORT = list(3L, 2, 3L), X.PERS = list(3, 3, 3L), X.DOORS = list(3, 3, 3L), LUGGAGE = list(2L, 2L, 2), SAFETY = list(2, c(2, 3), 2) ), row.names = c(NA, -3L), class = "data.frame" ) # The same chart types as above, but using more varied alternatives data # Plot all Car$alternatives with points and lines plotalt_radar(Car, alts3) # Use different colors and fill polygons plotalt_radar(Car, alts3, colors = c("blue", "brown", "purple"), fill = TRUE) plotalt_radar(Car, alts3, colors = c("blue", "brown", "purple"), fillcolors = c("green", "red", "yellow"), fill = TRUE) # Draw separate charts plotalt_radar(Car, alts3, split = TRUE) plotalt_radar(Car, alts3, split = TRUE, fill = TRUE) # Draw separate charts, using the same color settings on all charts plotalt_radar(Car, alts3, split = TRUE, unicolors = c("red", "green")) plotalt_radar(Car, alts3, split = TRUE, unicolors = c("green", "darkgreen"), fill = TRUE) plotalt_radar(Car, alts3, split = TRUE, unicolors = c("red", "green"), circular = TRUE) }
Plot alternatives
with respect to a single attribute
.
plotalt1( model, attribute = model$first(), alternatives = NULL, colors = c("red", "black", "green"), pch = 20, size = 5, linetype = 2, margins = NULL, lm = NULL, ... )
plotalt1( model, attribute = model$first(), alternatives = NULL, colors = c("red", "black", "green"), pch = 20, size = 5, linetype = 2, margins = NULL, lm = NULL, ... )
model |
A DexiModel object. Required. |
attribute |
A single DexiAttribute selector. It may be an DexiAttribute object or
an argument to |
alternatives |
A |
colors |
|
pch |
Plotting character, see |
size |
|
linetype |
|
margins |
|
lm |
|
... |
Optional parameters passed to |
Standard scatterplot base::plot is used.
Draws a chart.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with respect to "TECH.CHAR." attribute plotalt1(Car, "TECH.CHAR.") # Plot the first Car alternative with respect to "MAINT.PRICE" attribute plotalt1(Car, "MAINT.PRICE", 1)
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with respect to "TECH.CHAR." attribute plotalt1(Car, "TECH.CHAR.") # Plot the first Car alternative with respect to "MAINT.PRICE" attribute plotalt1(Car, "MAINT.PRICE", 1)
Draw a scatterpolot of alternatives
with attribute1
and attribute2
on the
and
axis, respectively.
plotalt2( model, attribute1, attribute2, alternatives = NULL, colors = NULL, pch = 20, size = 5, margins = NULL, lm = NULL, pos = 4, offset = 1, ... )
plotalt2( model, attribute1, attribute2, alternatives = NULL, colors = NULL, pch = 20, size = 5, margins = NULL, lm = NULL, pos = 4, offset = 1, ... )
model |
A DexiModel object. Required. |
attribute1 |
First attribute. It may be an DexiAttribute object or
an argument to |
attribute2 |
Second attribute. It may be an DexiAttribute object or
an argument to |
alternatives |
A |
colors |
|
pch |
Plotting character, see |
size |
|
margins |
|
lm |
|
pos |
A position specifier for legent text, see |
offset |
When |
... |
Optional parameters passed to |
Standard scatterplot graphics::plot()
is used.
Continuous attributes are not supported.
Draws a chart.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with respect to "PRICE" and "TECH.CHAR." attributes plotalt2(Car, "PRICE", "TECH.CHAR.") # Plot the first Car alternative with respect to "BUY.PRICE" and "MAINT.PRICE" attributes plotalt2(Car, "BUY.PRICE", "MAINT.PRICE", 1)
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Plot all Car$alternatives with respect to "PRICE" and "TECH.CHAR." attributes plotalt2(Car, "PRICE", "TECH.CHAR.") # Plot the first Car alternative with respect to "BUY.PRICE" and "MAINT.PRICE" attributes plotalt2(Car, "BUY.PRICE", "MAINT.PRICE", 1)
Plus-Minus Analysis:
Investigate the effects of changing single attributes values on the evaluation of alternative
.
The values of discrete basic attributes ("input attributes") are changed, one attribute at a time,
by a particular number of steps downwards (minus
) and upwards (plus
),
while observing the changes of the target
attribute values.
plus_minus( model, alternative, target = model$first(), minus = .Machine$integer.max, plus = .Machine$integer.max, print = TRUE, as_character = FALSE, round = NULL, id = NULL, evaluate = FALSE, ... )
plus_minus( model, alternative, target = model$first(), minus = .Machine$integer.max, plus = .Machine$integer.max, print = TRUE, as_character = FALSE, round = NULL, id = NULL, evaluate = FALSE, ... )
model |
A DexiModel object. |
alternative |
Either a |
target |
The attribute on which effects are observed. Default: |
minus |
The maximum number of downward steps to be made for each input attribute.
Default: |
plus |
The maximum number of upward steps to be made for each input attribute.
Default: |
print |
|
as_character |
|
round |
An integer number, argument to |
id |
|
evaluate |
|
... |
Optional parameters for |
A data frame consisting of columns:
id
IDs of input attributes (unless excluded by the id
argument).
structure
Structure and names of input attributes (unless excluded by the id
argument).
-minus
to -1
Evaluation value of target
when decreasing the corresponding attribute value by the corresponding number of steps.
target$id
Original alternative
value assigned to the corresponding attribute id
.
1
to plus
Evaluation value of target
when increasing the corresponding attribute value by the corresponding number of steps.
Special values "["
and "]"
denote that it is not possible to decrease of increase, respectively,
the corresponding attributes value further.
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=c(1, 3)) alte <- Car$evaluate(alt) # Default plus-minus analysis, evaluating `alt`. plus_minus(Car, alt, evaluate = TRUE) # Plus-minus analysis of `alte`, using character strings, # no pretty-printing and excluding structure info. plus_minus(Car, alte, as_character=TRUE, print=FALSE, id = "id") # Plus-minus analysis on `target="PRICE"`, using character strings. plus_minus(Car, alt, target="PRICE", as_character=TRUE, evaluate=TRUE)
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=c(1, 3)) alte <- Car$evaluate(alt) # Default plus-minus analysis, evaluating `alt`. plus_minus(Car, alt, evaluate = TRUE) # Plus-minus analysis of `alte`, using character strings, # no pretty-printing and excluding structure info. plus_minus(Car, alte, as_character=TRUE, print=FALSE, id = "id") # Plus-minus analysis on `target="PRICE"`, using character strings. plus_minus(Car, alt, target="PRICE", as_character=TRUE, evaluate=TRUE)
A helper function: Initializes a data frame for plus_minus()
.
plus_minus_setup(evaluated, attributes, minus, plus)
plus_minus_setup(evaluated, attributes, minus, plus)
evaluated |
An evaluated alternative. |
attributes |
Vector of DexiAttribute objects involved in |
minus |
A single integer: Maximum steps down. |
plus |
A single integer: Maximum steps up. |
A data frame consisting of columns:
"id"
Attribute IDs.
"structure"
Attribute $structure() + $name
.
counts
Attributes' scale sizes.
low_bounds
Low bounds of attributes' values.
high_bounds
High bounds of attributes' values.
low_diff
Maximum possible value decrease given low_bound
and attribute scale.
high_diff
Maximum possible value increase given high_bound
and attribute scale.
evals
Alternative evaluation for the corresponding attribute (from evaluated
).
sets
evals
represented as value sets.
A helper function for selective_explanation()
: Pretty-prints its results.
print_selective_explanation(explanation)
print_selective_explanation(explanation)
explanation |
A list of lists,
containing selective explanation results produced by |
NULL
. Pretty-prints the contents of explanation
.
read_dexi()
reads a definition of a DEXi model from a .dxi
file or XML string.
read_dexi(dxi)
read_dexi(dxi)
dxi |
character(1). A |
A DexiModel RC object.
CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi)
CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi)
Numeric value(s) x
are assumed to lie within the [lb:hb]
interval.
The function "reverses" x
linearly so that x = lb
maps to hb
and x = hb
maps to lb
.
In DEXiR, this function is used to reverse values defined on a DexiScale from
"ascending" to "descending" order or vice versa.
reverse_value(x, lb, hb)
reverse_value(x, lb, hb)
x |
|
lb |
|
hb |
|
numeric()
. Reversed value
.
reverse_value(1, 1, 5) # 5 reverse_value(3, 1, 5) # 3 reverse_value(5, 1, 5) # 1 reverse_value(c(1, 3, 5), 1, 5) # c(5, 3, 1)
reverse_value(1, 1, 5) # 5 reverse_value(3, 1, 5) # 3 reverse_value(5, 1, 5) # 1 reverse_value(c(1, 3, 5), 1, 5) # c(5, 3, 1)
Values of decision rules are in .dxi
files encoded using character strings, where each
individual character encodes some function value. The encoding is zero-based, so that
"0"
represents the lowest ordinal number on the corresponding discrete scale.
rule_value(char)
converts a single character to the corresponding ordinal value.
rule_value(ch)
rule_value(ch)
ch |
A single character, such as |
Corresponding integer value.
rule_value("1") rule_value("Z")
rule_value("1") rule_value("Z")
Values of decision rules are in .dxi
files encoded using character strings, where each
individual character encodes some function value. The encoding is zero-based, so that
the character "0"
represents the lowest ordinal number on the corresponding discrete scale.
Encoding of characters is according to ASCII, starting with "0"
.
rule_values(str)
converts the character string to a numeric vector of corresponding
ordinal values.
rule_values(str, add = 0)
rule_values(str, add = 0)
str |
|
add |
An integer constant to be added to the resulting vector. The default is |
A numeric vector of the same length as str
.
rule_values("01122:") rule_values("01122:", add = 1)
rule_values("01122:") rule_values("01122:", add = 1)
A helper function for preparing alternatives' data for charts that involve multiple
attributes (such as plotalt_parallel()
) and plotalt_radar()
).
scale_alternatives()
carries out three main operations:
Aggregates DEXi values, represented by sets and distributions,
into single numeric values, using one of the aggregate
operators:
"minmax"
, "min"
, "max"
or "mean"
,
scales the aggregated values to the [0,1]
interval so that they can be
drawn uniformly on multiple chart axes,
optionally "shifts" the values by a small amount to avoid overlapping chart lines.
scale_alternatives( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01 )
scale_alternatives( model, alternatives = NULL, attids = NULL, aggregate = c("minmax", "min", "max", "mean", "none"), name = "name", shift = 0.01 )
model |
A DexiModel object. Required. |
alternatives |
A |
attids |
|
aggregate |
Determines how to aggregate DEXi values that are represented/interpreted
as sets in
Any distributions that appear in |
name |
|
shift |
|
A list containing the elements:
data
A data frame containing the aggregated/scaled/shifted numeric values.
nalt
The number of alternatives. Notice that with aggregate = "minmax"
,
data
contains twice as many rows.
groups
A numeric vector mapping data
rows to alternatives
' indices.
altnames
Names of alternatives.
plotalt_parallel()
), plotalt_radar()
)
scale_of
scale_of(obj)
scale_of(obj)
obj |
A DexiAttribute or DexiScale. |
A DexiScale associated with obj
, or NA
for an undefined scale.
Check and interpret value
on scale
.
scale_value(value, scale)
scale_value(value, scale)
value |
A wide range of possible value types, including integer, double, character and list vectors. |
scale |
A DexiScale or derived object. |
The result is produced depending on value
and scale
according to the following tables.
For any scale type:
value result ------------------------------+------------------ NULL NULL length(value == 0) NULL NA scale$full_range() other types ERROR value contains any NULL or NA ERROR ------------------------------+------------------
For continuous scales:
value result ------------------------------+------------------ length(value != 1) ERROR character ERROR named object ERROR length(value == 1) unclass(value) ------------------------------+------------------
For discrete scales:
value result ------------------------------+------------------ distribution class value all-integer numeric vector value non all-integer numeric vector distribution(value) "*" or "undef"... scale$full_range() list of value names matched value set list of name=p distribution(value) ------------------------------+------------------
# Examples of successfully checked (witout error) values on a continuous scale scl <- DexiContinuousScale() scale_value(NULL, scl) # NA scale_value(c(), scl) # NA scale_value(list(), scl) # NA scale_value(character(), scl) # NA scale_value(NA, scl) # NA scale_value(c(NA), scl) # NA scale_value(15.5, scl) # 15.5 scale_value(distribution(15.5), scl) # 15.5 # Examples of successfully checked (without error) values on a discrete scale scl <- DexiDiscreteScale(values = c("low", "med", "high")) scale_value(NULL, scl) # NA scale_value(c(), scl) # NA scale_value(list(), scl) # NA scale_value(NA, scl) # NA scale_value("*", scl) # 1:3 scale_value("Undefined", scl) # 1:3 scale_value(2, scl) # 2 scale_value(c(-1, 2, 4), scl) # c(-1, 2, 4)) scale_value(distribution(c(-1, 2, 4)), scl) # distribution(c(-1, 2, 4))) scale_value(c(-1, 2.2, 4), scl) # distribution(c(-1, 2.2, 4))) scale_value("high", scl) # 3 scale_value(c("low", "high"), scl) # c(1,3)) v <- c(0.5, 0.4) names(v) <- c("low", "high") scale_value(v, scl) # distribution(c(0.5, 0, 0.4))) scale_value(list(high = 1.1, low = 2.2), scl) # distribution(c(2.2, 0, 1.1)))
# Examples of successfully checked (witout error) values on a continuous scale scl <- DexiContinuousScale() scale_value(NULL, scl) # NA scale_value(c(), scl) # NA scale_value(list(), scl) # NA scale_value(character(), scl) # NA scale_value(NA, scl) # NA scale_value(c(NA), scl) # NA scale_value(15.5, scl) # 15.5 scale_value(distribution(15.5), scl) # 15.5 # Examples of successfully checked (without error) values on a discrete scale scl <- DexiDiscreteScale(values = c("low", "med", "high")) scale_value(NULL, scl) # NA scale_value(c(), scl) # NA scale_value(list(), scl) # NA scale_value(NA, scl) # NA scale_value("*", scl) # 1:3 scale_value("Undefined", scl) # 1:3 scale_value(2, scl) # 2 scale_value(c(-1, 2, 4), scl) # c(-1, 2, 4)) scale_value(distribution(c(-1, 2, 4)), scl) # distribution(c(-1, 2, 4))) scale_value(c(-1, 2.2, 4), scl) # distribution(c(-1, 2.2, 4))) scale_value("high", scl) # 3 scale_value(c("low", "high"), scl) # c(1,3)) v <- c(0.5, 0.4) names(v) <- c("low", "high") scale_value(v, scl) # distribution(c(0.5, 0, 0.4))) scale_value(list(high = 1.1, low = 2.2), scl) # distribution(c(2.2, 0, 1.1)))
A vectorized version of scale_value
.
scale_values(values, scale)
scale_values(values, scale)
values |
A list of values. For possible value types, see |
scale |
A DexiScale or derived object. |
A list determined as lapply(values, function (v) scale_value(v, scale))
.
Select from alt
only those attributes whose values have the given quality
.
Used primarily in selective_explanation()
.
select_quality(model, alt, quality)
select_quality(model, alt, quality)
model |
A DexiModel object. |
alt |
|
quality |
Requested |
alt
containing only values that have the requested quality.
value_qualities()
, selective_explanation()
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=c(1, 3)) alte <- Car$evaluate(alt) alts <- select_quality(Car, alte, "bad") names(alts) # c("CAR", "PRICE", "MAINT.PRICE", "TECH.CHAR.", "SAFETY") alts <- select_quality(Car, alte, "none") names(alts) # c("MAINT.PRICE", "X.DOORS", "LUGGAGE") alts <- select_quality(Car, alte, "good") names(alts) # c("CAR", "PRICE", "BUY.PRICE", "MAINT.PRICE", "TECH.CHAR.", "COMFORT", "X.PERS", "SAFETY")
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=c(1, 3)) alte <- Car$evaluate(alt) alts <- select_quality(Car, alte, "bad") names(alts) # c("CAR", "PRICE", "MAINT.PRICE", "TECH.CHAR.", "SAFETY") alts <- select_quality(Car, alte, "none") names(alts) # c("MAINT.PRICE", "X.DOORS", "LUGGAGE") alts <- select_quality(Car, alte, "good") names(alts) # c("CAR", "PRICE", "BUY.PRICE", "MAINT.PRICE", "TECH.CHAR.", "COMFORT", "X.PERS", "SAFETY")
Selective Explanation: Displays subtrees of alternatives' values in which values are particularly weak (value quality is "bad") and particularly strong (value quality is "good").
selective_explanation( model, alternatives = NULL, print = TRUE, as_character = FALSE, round = NULL, id = NULL, evaluate = FALSE, ... )
selective_explanation( model, alternatives = NULL, print = TRUE, as_character = FALSE, round = NULL, id = NULL, evaluate = FALSE, ... )
model |
A DexiModel object. Required. |
alternatives |
A |
print |
|
as_character |
|
round |
An integer number, argument to |
id |
|
evaluate |
|
... |
Optional parameters for |
A list of lists: For each alternative contains a list of two data.frames, corresponding
to "bad"
and "good"
qualities, respectively.
May be pretty-printed using print_selective_explanation()
.
value_qualities()
, value_text()
, print_selective_explanation()
, evaluate()
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Print selective explanation of two Car$alternatives. selective_explanation(Car) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=c(1, 3)) alte <- Car$evaluate(alt) # Print selective explanation of `alte`. selective_explanation(Car, alte) # Print selective explanation of both `alt` and `alte`. selective_explanation(Car, rbind.data.frame(alt, alte))
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Print selective explanation of two Car$alternatives. selective_explanation(Car) alt <- Car$alternative("MyCar", BUY.PRICE="low", MAINT.PRICE="*", X.PERS="more", X.DOORS="4", LUGGAGE=2, SAFETY=c(1, 3)) alte <- Car$evaluate(alt) # Print selective explanation of `alte`. selective_explanation(Car, alte) # Print selective explanation of both `alt` and `alte`. selective_explanation(Car, rbind.data.frame(alt, alte))
Set values of a single decision alternative and represent it with a data frame. Usually, only input values are set in this way. The data frame can then be evaluated to set the values of output attributes.
set_alternative(model, alternative, ...)
set_alternative(model, alternative, ...)
model |
A DexiModel object. Required. |
alternative |
|
... |
A list of parameters specifying the values of the newly created decision alternative.
Each parameter is expected to be in the form There are several possible ways to specify
For attributes associated with continuous scales,
only |
A one-row data frame with columns corresponding to model
's attributes, collectively
representing a single decision alternative. The columns not copied from alternative
(as a data frame)
nor set by any parameter contain NA
s.
DEXiR-package notes on values in DEXi models.
Convert a DEXi value set to DEXi value distribution.
set_to_distr(set, length = 0)
set_to_distr(set, length = 0)
set |
Normally a numeric vector containing integer numbers. |
length |
The required length of the resulting distribution vector. The actual length
is determined as |
A distribution object of length length
. Arguments that
are already distributions are returned "as is". Input vectors of length 0 and other types
of objects return NA
.
DEXiR-package, distribution, distr_to_set()
set_to_distr(c(1, 3, 4)) set_to_distr(c(1, 3, 4), length = 5) set_to_distr(c(1, 3, 4), length = 0)
set_to_distr(c(1, 3, 4)) set_to_distr(c(1, 3, 4), length = 5) set_to_distr(c(1, 3, 4), length = 0)
A helper function for making colors
transparent.
transparent_colors(colors, percent = 50)
transparent_colors(colors, percent = 50)
colors |
A vector of color numbers or names. |
percent |
Required color transparency, in the range |
Requires installed package "grDevices".
A vector of colors of the same length as colors
.
transparent_colors(c("red", "green", "blue"), 50) # c("#FF00007F", "#00FF007F", "#0000FF7F")
transparent_colors(c("red", "green", "blue"), 50) # c("#FF00007F", "#00FF007F", "#0000FF7F")
Convert names
strings to ID strings that are unique and conformant
with R's syntactic rules for variable names.
unique_names(names, reserved = c())
unique_names(names, reserved = c())
names |
|
reserved |
|
character()
.
Returns a vector of qualities corresponding to consecutive elements of value
.
In contrast with DexiScale$value_quality(value)
, which can handle only single values,
this function can handle value
arguments that contain multiple elements,
such as value sets and distributions.
value_qualities(value, scale)
value_qualities(value, scale)
value |
A DEXi value, internal representation: numeric value or vector, or distribution. |
scale |
A DexiScale or derived object. |
A vector consisting of EnumQuality
elements corresponding to individual value
elements.
scl <- DexiDiscreteScale(values = c("low", "med", "high")) value_qualities(1, scl) # "bad" value_qualities(1:3, scl) # c("bad", "none", "good") value_qualities(c(3, 2), scl) # c("good", "none")
scl <- DexiDiscreteScale(values = c("low", "med", "high")) value_qualities(1, scl) # "bad" value_qualities(1:3, scl) # c("bad", "none", "good") value_qualities(c(3, 2), scl) # c("good", "none")
Converts a DEXi value
to a human-readable character string that can be printed.
Used, for instance, by DexiModel$as_character()
.
value_text(value, scale, round = NULL)
value_text(value, scale, round = NULL)
value |
Any DEXi value type (see DEXiR-package). |
scale |
A DexiScale or derived object. |
round |
An integer number. Indicates the number of decimals for
rounding numeric values prior to printing. If |
character.
scl <- DexiDiscreteScale(values = c("low", "med", "high")) value_text(NA, scl) value_text(1, scl) value_text(c(1, 3), scl) value_text(distribution(0.1, 0.2, 0.3), scl)
scl <- DexiDiscreteScale(values = c("low", "med", "high")) value_text(NA, scl) value_text(1, scl) value_text(c(1, 3), scl) value_text(distribution(0.1, 0.2, 0.3), scl)
value_to_set
value_to_set(value, scale)
value_to_set(value, scale)
value |
A DEXi value, internal representation: numeric value or vector, or distribution. |
scale |
A DexiScale or derived object. |
An integer vector or NA
for: non-discrete scale, NA
/NULL
value(s), non-integer value(s).
scl <- DexiDiscreteScale(values = c("low", "med", "high")) value_to_set(1, scl) # 1 value_to_set(1:2, scl) # c(1, 2) value_to_set(c(1,3), scl) # c(1, 3) value_to_set(distribution(1, 0, 0.5), scl) # c(1, 3)
scl <- DexiDiscreteScale(values = c("low", "med", "high")) value_to_set(1, scl) # 1 value_to_set(1:2, scl) # c(1, 2) value_to_set(c(1,3), scl) # c(1, 3) value_to_set(distribution(1, 0, 0.5), scl) # c(1, 3)
Convert numbers to a DEXi string. Implements the reverse operation of rule_values()
.
values_to_str(vals, add = 0)
values_to_str(vals, add = 0)
vals |
Numeric vector, containing ordinal values. |
add |
An integer constant to be added to |
A string representing DEXi's representation of ordinal values. Fails when
vals + add
contains negative numbers.
values_to_str(c(0, 1, 1, 2, 2, 10, 12)) values_to_str(c(1, 2, 2, 3, 3, 11, 13), -1)
values_to_str(c(0, 1, 1, 2, 2, 10, 12)) values_to_str(c(1, 2, 2, 3, 3, 11, 13), -1)
Write out alternatives
' data. First convert DEXi alternatives to a data frame using
export_alternatives()
and then write it to a file.
write_alternatives( model, alternatives = NULL, file = "", quote = FALSE, format = c("tab", "csv", "csv2"), ... )
write_alternatives( model, alternatives = NULL, file = "", quote = FALSE, format = c("tab", "csv", "csv2"), ... )
model |
A DexiModel object. Required. |
alternatives |
A |
file |
Write the data frame contents to a file.
When |
quote |
|
format |
One of |
... |
Optional parameters to |
Writes a "tab"- or "csv"-formatted alternatives
' data to a file,
console or clipboard. This data is meant to be subsequently imported to
'DEXi' software.
export_alternatives()
, write.table()
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Write both Car alternatives to console write_alternatives(Car, file = "")
# Load "Car.dxi" CarDxi <- system.file("extdata", "Car.dxi", package = "DEXiR") Car <- read_dexi(CarDxi) # Write both Car alternatives to console write_alternatives(Car, file = "")