Purpose

Identify the relationship between matrices. For example, it statistically tests whether spatial data are related to measurement data or not.

Required Packages

For conducting the Mantel test in R, we need to use a package such as ade4 or vegan. Currently, while vegan supports both simple and partial Mantel test, ade4 supports simple Mantel test only.

Fortunately, regardless of what package you are using, the process is almost identical. The difference is only the name of function.

Using vegan package:

Step 1. Load library

library(vegan)

Step 2. Input data

Load data either from Web or local file.

From Web:

ozone <- read.table("https://stats.idre.ucla.edu/stat/r/faq/ozone.csv", sep=",", header=T)

From local file. File should be located in the project folder.

ozone <- read.table("ozone.csv", sep=",", header=T)

These are the top 10 rows of the data we are using for this tutorial.

Station Av8top Lat Lon
60 7.225806 34.13583 -117.9236
69 5.899194 34.17611 -118.3153
72 4.052885 33.82361 -118.1875
74 7.181452 34.19944 -118.5347
75 6.076613 34.06694 -117.7514
84 3.157258 33.92917 -118.2097
85 5.201613 34.01500 -118.0597
87 4.717742 34.06722 -118.2264
88 6.532258 34.08333 -118.1069
89 7.540323 34.38750 -118.5347

Inspect the structure of data to determine appropriate pre-processing method. It indicates there are 32 rows and 4 columns(Station, Av8top, Lat, Lon). Among columns, Lat and Lon is location data and Av8top is measurement data.

str(ozone)
## 'data.frame':    32 obs. of  4 variables:
##  $ Station: int  60 69 72 74 75 84 85 87 88 89 ...
##  $ Av8top : num  7.23 5.9 4.05 7.18 6.08 ...
##  $ Lat    : num  34.1 34.2 33.8 34.2 34.1 ...
##  $ Lon    : num  -118 -118 -118 -119 -118 ...

Show first 10 rows for quick check.

head(ozone, n=10)
##    Station   Av8top      Lat       Lon
## 1       60 7.225806 34.13583 -117.9236
## 2       69 5.899194 34.17611 -118.3153
## 3       72 4.052885 33.82361 -118.1875
## 4       74 7.181452 34.19944 -118.5347
## 5       75 6.076613 34.06694 -117.7514
## 6       84 3.157258 33.92917 -118.2097
## 7       85 5.201613 34.01500 -118.0597
## 8       87 4.717742 34.06722 -118.2264
## 9       88 6.532258 34.08333 -118.1069
## 10      89 7.540323 34.38750 -118.5347

Step 3. Pre-processing

At first, calculate the distance between pairs using dist function.

# Calculate distance matrix for locations
station.dists <- dist(cbind(ozone$Lon, ozone$Lat)) 

# Calculate distance matrix for measurements
ozone.dists <- dist(ozone$Av8top)

# Control matrix
# Create a matrix arbitrarily for demonstration purpose only
c.dists <-  dist(ozone$Av8top * runif(length(ozone$Av8top)))

Then, display data in matrix to verify. (only first 5 rows and columns)

# Print matrix
as.matrix(station.dists)[1:5, 1:5]
##           1         2         3         4         5
## 1 0.0000000 0.3937326 0.4088031 0.6144127 0.1854888
## 2 0.3937326 0.0000000 0.3749446 0.2206810 0.5743590
## 3 0.4088031 0.3749446 0.0000000 0.5116772 0.4994034
## 4 0.6144127 0.2206810 0.5116772 0.0000000 0.7944601
## 5 0.1854888 0.5743590 0.4994034 0.7944601 0.0000000
as.matrix(ozone.dists)[1:5, 1:5]
##          1        2        3        4        5
## 1 0.000000 1.326612 3.172921 0.044354 1.149193
## 2 1.326612 0.000000 1.846309 1.282258 0.177419
## 3 3.172921 1.846309 0.000000 3.128567 2.023728
## 4 0.044354 1.282258 3.128567 0.000000 1.104839
## 5 1.149193 0.177419 2.023728 1.104839 0.000000

Visualize matrices. In order to visually compare the similarity, matrices are converted to correlation matrix before drawing plot.

Step 4. Analysis

Run the Mantel test with 9999 repetitions.

# Run simple Mantel test
results <- mantel(station.dists, ozone.dists, permutations = 9999)

# Run partial Mantel test
results_partial <- mantel.partial(station.dists, ozone.dists, c.dists, permutations = 9999)

Step 5. Ouput

# Results of simple Mantel test
show(results)
## 
## Mantel statistic based on Pearson's product-moment correlation 
## 
## Call:
## mantel(xdis = station.dists, ydis = ozone.dists, permutations = 9999) 
## 
## Mantel statistic r: 0.1636 
##       Significance: 0.0286 
## 
## Upper quantiles of permutations (null model):
##   90%   95% 97.5%   99% 
## 0.097 0.134 0.170 0.208 
## Permutation: free
## Number of permutations: 9999

From the results of the simple Mantel test, the r is 0.1636308, and the p-value is 0.0286(less than 0.05). Thus, the null hypothesis is rejected and the research hypothesis is taken.

# Results of partial Mantel test
show(results_partial)
## 
## Partial Mantel statistic based on Pearson's product-moment correlation 
## 
## Call:
## mantel.partial(xdis = station.dists, ydis = ozone.dists, zdis = c.dists,      permutations = 9999) 
## 
## Mantel statistic r: 0.1629 
##       Significance: 0.0292 
## 
## Upper quantiles of permutations (null model):
##   90%   95% 97.5%   99% 
## 0.101 0.139 0.169 0.205 
## Permutation: free
## Number of permutations: 9999

From the results of the partial Mantel test, the r is 0.162855, and the p-value is 0.0292(less than 0.05). Thus, the null hypothesis is rejected and the research hypothesis is taken.

Conclusion

The p-value of 0.0292 indicates that the relationship between spatial data and measurement data is statistically significant. Therefore, we can conclude that the location and ozone value are related to each other.

Using ade4 package

Step 1. Load library

library(ade4)

Step 2. Input data

Load data either from Web or local file.

From Web:

ozone <- read.table("https://stats.idre.ucla.edu/stat/r/faq/ozone.csv", sep=",", header=T)

From local file. File should be located in the project folder.

ozone <- read.table("ozone.csv", sep=",", header=T)

Inspect data structure to determine appropriate pre-processing method. It shows there are 32 rows and 4 columns(Station, Av8top, Lat, Lon). Among columns, Lat and Lon is location data and Av8top is measurement data.

str(ozone)
## 'data.frame':    32 obs. of  4 variables:
##  $ Station: int  60 69 72 74 75 84 85 87 88 89 ...
##  $ Av8top : num  7.23 5.9 4.05 7.18 6.08 ...
##  $ Lat    : num  34.1 34.2 33.8 34.2 34.1 ...
##  $ Lon    : num  -118 -118 -118 -119 -118 ...

Show first 10 rows for quick check.

head(ozone, n=10)
##    Station   Av8top      Lat       Lon
## 1       60 7.225806 34.13583 -117.9236
## 2       69 5.899194 34.17611 -118.3153
## 3       72 4.052885 33.82361 -118.1875
## 4       74 7.181452 34.19944 -118.5347
## 5       75 6.076613 34.06694 -117.7514
## 6       84 3.157258 33.92917 -118.2097
## 7       85 5.201613 34.01500 -118.0597
## 8       87 4.717742 34.06722 -118.2264
## 9       88 6.532258 34.08333 -118.1069
## 10      89 7.540323 34.38750 -118.5347

Step 3. Pre-processing

At first, calculate the distance between pair using dist function. We prepared three matrices for partial Mantel test.

# Calculate distance matrix for locations
station.dists <- dist(ozone[,c('Lon','Lat')]) 

# Calculate distance matrix for measurements
ozone.dists <- dist(ozone$Av8top)

Then, display data in matrix to verify. (only first 5 rows and columns)

# Print matrix
as.matrix(station.dists)[1:5, 1:5]
##           1         2         3         4         5
## 1 0.0000000 0.3937326 0.4088031 0.6144127 0.1854888
## 2 0.3937326 0.0000000 0.3749446 0.2206810 0.5743590
## 3 0.4088031 0.3749446 0.0000000 0.5116772 0.4994034
## 4 0.6144127 0.2206810 0.5116772 0.0000000 0.7944601
## 5 0.1854888 0.5743590 0.4994034 0.7944601 0.0000000
as.matrix(ozone.dists)[1:5, 1:5]
##          1        2        3        4        5
## 1 0.000000 1.326612 3.172921 0.044354 1.149193
## 2 1.326612 0.000000 1.846309 1.282258 0.177419
## 3 3.172921 1.846309 0.000000 3.128567 2.023728
## 4 0.044354 1.282258 3.128567 0.000000 1.104839
## 5 1.149193 0.177419 2.023728 1.104839 0.000000

Visualize matrices.

Step 4. Analysis

Run the Mantel test with 9999 repetitions.

# Run simple Mantel test
results <- mantel.rtest(station.dists, ozone.dists, nrepet = 9999)

Step 5. Ouput

# Results of simple Mantel test
show(results)
## Monte-Carlo test
## Call: mantel.rtest(m1 = station.dists, m2 = ozone.dists, nrepet = 9999)
## 
## Observation: 0.1636308 
## 
## Based on 9999 replicates
## Simulated p-value: 0.0297 
## Alternative hypothesis: greater 
## 
##      Std.Obs  Expectation     Variance 
## 2.2099360409 0.0006243055 0.0054406448

Source code

#HOW CAN I PERFORM A MANTEL TEST IN R? | R FAQ

library(ade4)
library(vegan)

# Load data from Web
ozone <- read.table("https://stats.idre.ucla.edu/stat/r/faq/ozone.csv", sep=",", header=T)
# or Load data from local file
#ozone <- read.table("ozone.csv", sep=",", header=T)

# Print data
str(ozone)
head(ozone, n=10)

# Calculate distance matrix for locations
#station.dists <- dist(cbind(ozone$Lon, ozone$Lat)) 
station.dists <- dist(ozone[,c('Lon','Lat')]) # All rows from Lon, Lat columns

# Calculate distance matrix for measurements
ozone.dists <- dist(ozone$Av8top)

# Control matrix
# Create a matrix arbitrarily for demonstration purpose only
c.dists <-  dist(ozone$Av8top * runif(length(ozone$Av8top)))

# Print matrix
as.matrix(station.dists)[1:5, 1:5]
as.matrix(ozone.dists)[1:5, 1:5]
as.matrix(c.dists)[1:5, 1:5]

# Using ade4 package
# Run simple Mantel test
results <- mantel.rtest(station.dists, ozone.dists, nrepet = 9999)
show(results)

# Using vegan package
# Run simple Mantel test
results <- mantel(station.dists, ozone.dists, permutations = 9999)
show(results)

# Run partial Mantel test
results_partial <- mantel.partial(station.dists, ozone.dists, c.dists, permutations = 9999)
show(results_partial)

References

HOW CAN I PERFORM A MANTEL TEST IN R? | R FAQ