1 Introduction of the ahpsurvey package

The 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)

1.1 The e-Palette survey dataset

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.

2 Individual and Aggregated priorities

2.1 Creating pairwise comparison matrices

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()
FD TC SR HC LL CF
FD 1.000 0.250 9 0.333 0.200 3.000
TC 4.000 1.000 9 4.000 1.000 3.000
SR 0.111 0.111 1 0.111 0.111 0.111
HC 3.000 0.250 9 1.000 0.200 0.250
LL 5.000 1.000 9 5.000 1.000 3.000
CF 0.333 0.333 9 4.000 0.333 1.000

2.2 Individual preference weights

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 mean
    • geometric: the geometric mean
    • rootmean: the square root of the sum of the squared value
    • eigen: 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

2.3 Aggregated preference weights

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 mean
    • geometric: the geometric mean
    • rootmean: the square root of the sum of the squared value
    • eigen: 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 mean
    • tgmean trimmed geometric mean
    • sd 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

Saaty, Thomas L. 2003. “Decision-Making with the AHP: Why Is the Principal Eigenvector Necessary.” European Journal of Operational Research 145 (1): 85–91. https://doi.org/10.1016/s0377-2217(02)00227-8.