In this tutorial we show how to call a local R script in diviz implementing a weighted sum.
This tutorial focusses on the following aspects:
- Writing the weighted sum script in R;
- Adding this program to diviz.
This tutorial requires that you have installed R on your computer (https://www.r-project.org/) and that you have installed the RXMCDA package (XMCDA parsing library for R, available via the CRAN). To install the RXMCDA package, just do it in R via the command:
install.packages("RXMCDA", dependencies=TRUE)
Create a new empty workflow (see this tutorial to learn how to do this) and drag and drop generic_program in the workspace. You should now have a program called generic_program-1 in your workspace with one input (infile1
) and one output (outfile1
).
If you double-click on generic_program-1, its properties window will open. There you can specify the number of inputs and outputs you need for your program. In this tutorial, we wish to implement a weighted sum program. We will therefore need 4 inputs: two inputs to define the alternatives and the criteria, an input for the performance table, and one for the weights of the criteria. Concerning the outputs, we will only produce one output, which contains the overall values of the input alternatives. We therefore select 4 inputs and 1 output.
To specify the commandline call for this program, enter the following in the cmdline field of the properties window of generic_program-1:
R --slave --vanilla --args infile1 infile2 infile3 infile4 outfile1
The arguments (“infile1”, …, “outfile1”) define the input and output file names.
Then check the Use a script option and enter the following in the textbox :
# Load the RXMCDA package (which in turn # will load the required XML package) library(RXMCDA) # Get the list of arguments behind the --args option args <- commandArgs(trailingOnly = TRUE) # Get the filenames from the arguments alternativesFile <- args[1] criteriaFile <- args[2] performanceTableFile <- args[3] criteriaWeightsFile <- args[4] overallValuesFile <- args[5] # Load the input files # See the documentation of the XML package for R # for further details on the xmlParse function treeAlternatives<-xmlTreeParse(alternativesFile,useInternalNodes=TRUE) treeCriteria<-xmlTreeParse(criteriaFile,useInternalNodes=TRUE) treePerformanceTable<-xmlTreeParse(performanceTableFile,useInternalNodes=TRUE) treeCriteriaWeights<-xmlTreeParse(criteriaWeightsFile,useInternalNodes=TRUE) # Read the MCDA data from the files # See the documentation of the RXMCDA package for R for further # details concerning this step, and for the description # of the output data critIDs <- getCriteriaIDs(treeCriteria)[[1]] altIDs <- getAlternativesIDs(treeAlternatives)[[1]] perfTable <- getPerformanceTables(treePerformanceTable,altIDs = altIDs, critIDs = critIDs)[[1]] critWeights <- getCriteriaValues(treeCriteriaWeights, critIDs)[[1]] # Calculate the weighted sum of the alternatives overallValues <- c() for (i in 1:dim(perfTable)[1]){ overallValues <- rbind(overallValues, c(i,sum(perfTable[i,]*t(critWeights[,2])))) } # Write the result file # We first create an empty XML tree outTree = newXMLDoc() # Then we specify the root node newXMLNode("xmcda:XMCDA", attrs=c("xsi:schemaLocation" = "http://www.decision-deck.org/2009/XMCDA-2.1.0 https://www.decision-deck.org/xmcda/_downloads/XMCDA-2.1.0.xsd"), suppressNamespaceWarning=TRUE, namespace = c("xsi" = "http://www.w3.org/2001/XMLSchema-instance", "xmcda" = "http://www.decision-deck.org/2009/XMCDA-2.1.0"), parent=outTree) # And finally we write the output data in the XML tree # Again, see the RXMCDA documentation for # further details on the putAlternativesValues function and its arguments putAlternativesValues(outTree, overallValues, rownames(perfTable), "overallValues") saveXML(outTree, file=overallValuesFile)
Instead of pasting everything in the script field of the properties window, you could have created a new file (let’s say “weightedSum.R”) and changed the command line to :
R --slave --vanilla --file=/path/to/weightedSum.R --args infile1 infile2 infile3 infile4 outfile1
Another option is to add the file of the script (let’s say “weightedSum.R”) to your workspace, and connect it to generic_program-1. To do so, you need to check the option ‘Provide the script as a file’, which adds an input called script
to the generic_program-1 box. You just have to connect the file representing your script to this entry. The command-line now becomes:
R --slave --vanilla --file=script --args infile1 infile2 infile3 infile4 outfile1
To check that your program works as expected, connect the following 4 input files to the correct input elements of generic_program-1:
alternatives.xml
toinfile1
criteria.xml
toinfile2
performanceTable.xml
toinfile3
criteriaWeights.xml
toinfile4
Then, execute the workflow and click on outfile1
to display the overall values of the input alternatives.
This example shows the basic usage of local R scripts in R. Note that we warmly recommend to do further tests in your scripts in order to increase its robustness. For example, you should encapsulate parts of the script in tryCatch
blocks to handle exceptions. Such errors could then be written to a second output file which would help the user to solve the execution problems. Furthermore, you should check the validity of the input files with respect to the XMCDA Schema. You could do that by using the checkXSD
function of the R package RXMCDA.
You can download the workflow bundled with the input files described in this tutorial from here
. See here for a tutorial on how to import such a workflow into diviz.