Rahpsurvey package (ver
0.4.1)ahpsurvey packageThe ahpsurvey package provides a workflow to quantify
and visualise inconsistent pairwise comparisons that aids researchers in
improving the AHP design and adopting appropriate analytically methods
for the AHP.
Install the package directly from CRAN (if you have not already installed the package)
# install.packages("ahpsurvey")And load the ahpsurvey library.
library(ahpsurvey)A Saaty scale is composed of 9 items on each end (17 options per
pairwise comparison) where decision-makers are asked to indicate how
much attribute/ characteristic A is more preferred to B (or vice versa),
and how much it is preferred in a 9-point scale. Respondents are asked
to make pairwise comparisons for a range of attributes, and indicate
their priorities for each of them. Afterwards, we load the data needed,
cleaned_data.csv, which consists of cleaned data of 17
individuals based on the raw data collected from students via the
distributed questionnaire (designed by QuestionPro website at https://questionpro.com/t/AQ41hZtckV):
| ID | FD_TC | FD_SR | FD_HC | FD_LL | FD_CF | TC_SR | TC_HC | TC_LL | TC_CF | SR_HC | SR_LL | SR_CF | HC_LL | HC_CF | LL_CF |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 4 | -9 | 3 | 5 | -3 | -9 | -4 | 1 | -3 | 9 | 9 | 9 | 5 | 4 | -3 |
| 2 | 1 | -9 | 8 | 3 | -3 | -9 | 5 | 3 | -3 | 9 | 9 | 9 | -9 | -9 | -5 |
| 3 | 9 | -5 | 9 | 9 | 9 | -9 | 9 | 9 | 9 | 9 | 9 | 9 | -3 | -2 | -4 |
| 4 | -8 | -9 | -6 | -7 | -8 | -9 | -4 | 2 | 8 | 9 | 8 | 8 | -8 | -7 | 8 |
| 5 | -7 | -6 | -6 | -6 | 7 | 4 | 3 | -4 | 9 | 4 | 5 | 9 | 2 | 9 | 9 |
| 6 | -5 | -7 | -3 | -6 | -8 | -6 | -2 | -5 | -7 | 6 | 5 | 3 | -7 | -4 | -4 |
| 7 | 5 | -5 | 9 | 3 | -3 | -5 | 4 | -3 | -2 | 6 | 3 | 3 | -9 | -9 | -2 |
| 8 | -6 | -9 | 7 | -2 | -4 | -8 | 8 | 6 | -3 | 9 | 8 | 5 | -5 | -9 | -4 |
| 9 | -2 | -8 | 8 | -5 | 1 | -2 | 6 | 1 | 1 | 8 | 1 | 5 | -9 | -8 | 4 |
| 10 | -7 | -7 | 7 | -6 | -7 | -4 | 8 | -7 | -3 | 8 | -6 | 6 | -8 | -6 | -7 |
| 11 | -4 | -7 | 4 | 5 | 5 | -5 | 8 | 7 | 7 | 9 | 9 | 9 | -2 | 2 | 1 |
| 12 | -7 | -7 | -5 | -7 | 9 | -7 | -7 | -7 | 9 | 8 | 6 | 9 | -7 | 9 | 9 |
| 13 | -5 | -7 | 5 | -4 | 7 | -5 | 6 | -5 | 7 | 7 | 5 | 7 | -7 | 5 | 9 |
| 14 | 2 | -3 | 5 | 4 | 1 | -5 | 1 | -2 | -2 | 5 | 4 | 6 | -5 | -5 | 1 |
| 15 | -9 | 2 | -9 | -9 | -7 | 9 | 4 | -3 | 7 | -9 | -9 | -6 | -8 | -5 | 7 |
| 16 | 9 | 1 | 9 | 1 | 9 | -7 | 9 | -7 | 9 | 9 | 4 | 9 | -9 | -9 | 9 |
| 17 | -8 | -4 | -5 | -6 | -3 | 2 | 4 | 1 | 2 | 4 | 4 | 5 | -5 | -3 | 3 |
In the data:
FD: Food delivery
TC: Tourism, cultural exchange
SR: Shower room
HC: Health care
LL: Luggage / Locker Storage
CF: Cafe
atts <- c("FD", "TC", "SR", "HC", "LL", "CF")
dict <- c("FD" = "Food delivery",
"TC" = "Tourism, cultural exchange",
"SR" = "Shower rooms",
"HC" = "Health care",
"LL" = "Luggage / Locker Storage",
"CF" = "Cafe")The simulated dataset consists of fifteen pairwise comparisons of 6 attributes, which are “Food delivery”, “Tourism, cultural exchange”, “Shower room”, “Health care”, “Luggage / Locker Storage” and “Cafe.” An individual compares the attributes in a pairwise attribute comparison; if “Food delivery” is more important than “Tourism, cultural exchange” by 2 units on the Saaty scale, the dataset will code it as -2. This is essential to bear in mind as we move on.
Based on the Saaty scale, a pairwise comparison matrix of \(N\) attributes for the \(k^{th}\) individual is obtained:
\[ \mathbf{S_k} =\begin{pmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,N} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,N} \\ \vdots & \vdots & a_{i,j} & \vdots \\ a_{N,1} & a_{N,2} & \cdots & a_{N,N} \end{pmatrix} \]
Where \(a_{i,j}\) represents the pairwise comparison between the attribute \(i\) and \(j\). If \(i\) is more important than \(j\) for 6 units, \(a_{i,j} = 6\) and \(a_{j,i} = \frac{1}{6}\), i.e. the reciprocal. Data must be reformatted into this pairwise comparison matrix format to proceed.
The reformatting of the survey data (with one row per individual)
into such a matrix necessary for further analysis is cumbersome for
researchers. Furthermore, as researchers conducting the AHP as an
integrated part of a survey, we typically receive data in the above
format: the pairwise comparisons are coded in positive and negative
numbers as opposed to reciprocals. In the case where the decision-maker
chose 6, the sensible codebook maker would code it as -6, which denotes
that Food delivery is more important than Tourism, cultural
exchange in 6 units for that decision-maker. For
ahp.mat to work, the value in A_B variable have to be the
importance A has over B in positive values. In this case, the values
should be converted from negative to positive, and the negative values
would be converted to its reciprocal in the pairwise matrix. When data
is coded in the above way, set negconvert = TRUE. If the
data is already coded in the reciprocal (as opposed to negatives), set
reciprocal = FALSE.
Some caveats prior to entering the data into the ahp.mat
function. ahp.mat does not recognise the names of the
original dataframe, and figures out which attribute corresponds to which
entirely based on the order of the columns. For example, when the
attributes are A, B, C and D, the dataframe should be ordered in
A_B, A_C, A_D, B_C, B_D, C_D, and the attributes listed as
c(A,B,C,D), in that order.
The ahp.mat function takes four arguments:
df: the dataframe
atts: a list of attributes in the correct
order
negconvert: whether to convert all positive values
to negative (logical, defaults to FALSE)
reciprocal: whether to convert negative values
(after negconvert) to its reciprocals (defaults to
TRUE).
The ahp.mat function creates a list of pairwise
comparison matrices for all decision-makers. As seen below, the pairwise
matrices resembles the original Saaty criteria weights, which is a good
sanity check.
The following only shows the first decision-maker’s pairwise comparison matrix:
AHP_data_mat <- ahp.mat(df = AHP_data, atts = atts, negconvert = TRUE)
AHP_data_mat %>% head(1) %>% kable()
|
The ahp.indpref function computes the individual
priorities of the decision-makers, and returns a data.frame
containing the preference weights of the decision-makers. The three
arguments are as follows:
ahpmat: The list of matrices created by
ahp.mat.
atts: a list of attributes in the correct
order.
method: It normalises the matrices so that all the
columns add up to 1, and then computes the averages of the row as the
preference weights of each attribute. Four modes of finding the averages
are available:
arithmetic: the arithmetic meangeometric: the geometric meanrootmean: the square root of the sum of the squared
valueeigen: the individual preference weights are computed
using the Dominant Eigenvalue’s method described in (Saaty 2003)Here the individual preference weights by using arithmetic mean method.
arithm_ind <- ahp.indpref(AHP_data_mat, atts, method = "arithmetic")
round(arithm_ind, 3) %>%
rownames_to_column('ID') %>%
kable()| ID | FD | TC | SR | HC | LL | CF |
|---|---|---|---|---|---|---|
| 1 | 0.123 | 0.292 | 0.021 | 0.111 | 0.316 | 0.137 |
| 2 | 0.102 | 0.110 | 0.021 | 0.520 | 0.183 | 0.064 |
| 3 | 0.040 | 0.097 | 0.021 | 0.361 | 0.282 | 0.199 |
| 4 | 0.419 | 0.118 | 0.020 | 0.193 | 0.072 | 0.178 |
| 5 | 0.224 | 0.058 | 0.053 | 0.075 | 0.076 | 0.514 |
| 6 | 0.428 | 0.218 | 0.030 | 0.189 | 0.088 | 0.047 |
| 7 | 0.094 | 0.186 | 0.037 | 0.519 | 0.099 | 0.064 |
| 8 | 0.187 | 0.083 | 0.022 | 0.496 | 0.160 | 0.052 |
| 9 | 0.165 | 0.075 | 0.039 | 0.552 | 0.047 | 0.122 |
| 10 | 0.232 | 0.113 | 0.061 | 0.454 | 0.072 | 0.069 |
| 11 | 0.094 | 0.048 | 0.022 | 0.275 | 0.249 | 0.312 |
| 12 | 0.200 | 0.144 | 0.022 | 0.096 | 0.048 | 0.489 |
| 13 | 0.136 | 0.087 | 0.027 | 0.238 | 0.051 | 0.461 |
| 14 | 0.089 | 0.232 | 0.039 | 0.371 | 0.146 | 0.123 |
| 15 | 0.317 | 0.037 | 0.398 | 0.124 | 0.023 | 0.101 |
| 16 | 0.032 | 0.153 | 0.027 | 0.482 | 0.048 | 0.259 |
| 17 | 0.433 | 0.050 | 0.060 | 0.226 | 0.081 | 0.150 |
The ahp.aggpref function computes the aggregated
priorities of all decision-makers using the specified methods. The
following arguments are given:
method: Same as ahp.indpref. It normalises
the matrices so that all the columns add up to 1, and then computes the
averages of the row as the preference weights of each attribute. Four
modes of finding the averages are available:
arithmetic: the arithmetic meangeometric: the geometric meanrootmean: the square root of the sum of the squared
valueeigen: the individual preference weights are computed
using the Dominant Eigenvalues method.aggmethod: how to aggregate the individual priorities.
arithmetic, geometric and
rootmean (same principle as method)tmean trimmed meantgmean trimmed geometric meansd returns the standard deviation from the arithmetic
mean.arithm_agg <- ahp.aggpref(AHP_data_mat, atts, method = "arithmetic", aggmethod = "arithmetic")
round(arithm_agg, 3) %>% t() %>% kable()| FD | TC | SR | HC | LL | CF |
|---|---|---|---|---|---|
| 0.195 | 0.124 | 0.054 | 0.311 | 0.12 | 0.197 |
REFERENCES