2022-05-24 @Atsushi Kawaguchi

The mand package provides functions for multivariate analysis for neuroimaging data.

library(mand)
## Loading required package: msma

Introduction

Template

One subject image as the template is available in the mand package. The coad to load it is as follows.

data(template)

The image is compressed because of storage and computation time. The dimension is confirmed as follows.

dim(template)
## [1] 30 36 30

The image is plotted by the coat function.

coat(template)

Other options with the plane argument (such as “axial,” “coronal,” “sagittal,” and “all”) are available. The default setting is “axial”. If the argument is specified as plane="all", three directional slices at a certain coordinate are plotted.

coat(x=template, plane="all")

Image Data Matrix

The imgdatamat function reads image files saved in the nifti format and creates data matrix with subjects in row and voxel in column (this example does not work).

fnames1 = c("data1.nii", "data2.nii")
imgmat = imgdatamat(fnames1, simscale=1/4)

The first argument is file names with the length equaling the number of subjects (the number of rows in the resulting data matrix). The second argument simscale is the image resize scale. In this example, the all sizes (number of voxel) for three direction was reduced into its quarter size. The output is the list form where the “S” is data matrix, the “brainpos” is a binary image indicating brain region, and the “imagedim” is image dimension. The ROI (Region Of Interest) volume is computed in the “roi” if the ROI argument is TRUE.

imgmat = imgdatamat(fnames1, simscale=1/4, ROI=TRUE)

Overlay

The resulting map from the statistical analysis such as the t statistics map from the SPM is represented with overlapping on the template. For example, the mand package has the average difference assuming Alzheimer’s disease and healthy subjects with the array format.

The overlay is implemented by the coat function.

data(diffimg)
coat(template, diffimg)

Atlas

Anatomical brain segmentation region is useful for the plot and the interpretation. For example, the Automated Anatomical Labeling (AAL) atlas is used. The data.frame has two columns (“ROIid” and “ROIname”) format.

data(atlasdatasets)
atlasname = "aal"
atlasdataset = atlasdatasets[[atlasname]]
head(atlasdataset)
##   ROIid                       ROIname
## 0     0                    Background
## 1     1               Left Precentral
## 2     2              Right Precentral
## 3     3         Left Superior Frontal
## 4     4        Right Superior Frontal
## 5     5 Left Superior Frontal Orbital

It is also neccesary to prepare the array data.

data(atlas)
tmpatlas = atlas[[atlasname]]
dim(tmpatlas)
## [1] 30 36 30

It has the ROIid as the element.

tmpatlas[11:15,11:15,10]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   56   56   56   56   56
## [2,]   98   98   98   56   56
## [3,]   98   98   96   96   96
## [4,]   98   98   96   96   94
## [5,]   98   96   96   96  110

The anatomical region can be plotted by the coat function with regionplot=TRUE.

coat(template, tmpatlas, regionplot=TRUE, 
atlasdataset=atlasdataset, ROIids = c(1:2, 37:40), 
regionlegend=TRUE)

The resulting map can be converted into the summary of the anatomical regions.

atlastable(tmpatlas, diffimg, atlasdataset, ROIids = c(1:2, 
37:40))
##    ROIid               ROIname sizepct sumvalue   Min.   Mean Max.
## 39    39  Left Parahippocampus   1.000  -20.387 -0.941 -0.001    0
## 38    38     Right Hippocampus   1.000  -14.914 -0.912  0.000    0
## 37    37      Left Hippocampus   1.000  -17.864 -0.823 -0.001    0
## 40    40 Right Parahippocampus   1.000  -20.822 -0.794 -0.001    0
## 1      1       Left Precentral   0.643  -14.288 -0.312  0.000    0
## 2      2      Right Precentral   0.698  -16.033 -0.286  0.000    0

The outputs are the number of voxel in the sizenum column, the percentage of the voxel in the sizepct column, and the minimum, mean, and maximum valued of the region of the overlaying map. The order of the table row is in the larger absolute value of the minimum or maximum values.

The brain image corresponding to the region of interest can be extracted as follows. First, we create a mask image in which the hippocampal region is represented by 1 and others by 0. Then the product of the template and the mask image is taken for each voxel.

hipmask = (tmpatlas == 37) + (tmpatlas == 38)
template2 = template * hipmask

The images generated by these processes are plotted from left to right in one slice.

par(mfrow=c(1,3), mar=rep(1,4))
coat(template, pseq=11, paron=FALSE)
coat(hipmask, pseq=11, paron=FALSE)
coat(template2, pseq=11, paron=FALSE)

The template image (left) and the mask image (middle) are multiplied voxel by voxel to obtain the only hippocampus region image (right).

The sum of the voxel values in the region is calculated as follows.

sum(template[which(hipmask==1, arr.ind = TRUE)])/1000
## [1] 185.9375

Such a value is calculated for each region and a dataset with ROI values is created.

Principal Component Analysis

Generate Simulation Data

The mand package has a function to generate simulation brain data from the base image, the difference image and the standard deviation image. These basic images are loaded as follows.

data(baseimg)
data(diffimg)
data(mask)
data(sdevimg)

The number of voxels in the original 3D image is as follows.

dim(baseimg)
## [1] 30 36 30

To understand the result easily, the difference region was restricted to Parahippocampus and Hippocampus.

diffimg2 = diffimg * (tmpatlas %in% 37:40)

An image data matrix with subjects in the rows and voxels in the columns was generated by using the simbrain function.

img1 = simbrain(baseimg = baseimg, diffimg = diffimg2, 
sdevimg=sdevimg, mask=mask, n0=20, c1=0.01, sd1=0.05)

The base image, the difference image and the standard deviation image were specified in the first three arguments. The out-of-brain region was specified by the mask argument, which was the binary image. The remaining arguments are the number of subjects per group, the coefficient multiplied by the difference image and the standard deviation for the noise.

The data matrix dimension was 40(subject) x 6422(voxel).

dim(img1$S)
## [1]   40 6422

The rec function creates the 3D image from the vectorized data (the first subject).

coat(rec(img1$S[1,], img1$imagedim, mask=img1$brainpos))

The standard deviation image is created from the resulting data matrix.

sdimg = apply(img1$S, 2, sd)
coat(template, rec(sdimg, img1$imagedim, mask=img1$brainpos))

Principal Component Analysis

If the input is a matrix, a principal component analysis is implemented by the msma function of the msma package. Principal component analysis with the number of components of 2 for the image data matrix is performed as follows.

(fit111 = msma(img1$S, comp=2))
## Call:
## msma.default(X = img1$S, comp = 2)
## 
## Numbers of non-zeros for X: 
##        comp1 comp2
## block1  6422  6422
## 
## Numbers of non-zeros for X super: 
## comp1 comp2 
##     1     1

The scatter plots for the score vectors specified by the argument v. The argument axes is specified by the two length vectors on which components are displayed.

plot(fit111, v="score", axes = 1:2, plottype="scatter")

The weight (loading) vectors can be obtained and reconstructed as follows.

midx = 1 ## the index for the modality
vidx = 1 ## the index for the component
Q = fit111$wbX[[midx]][,vidx]
outstat1 = rec(Q, img1$imagedim, mask=img1$brainpos)

The reconstructed loadings as image is overlayed on the template.

coat(template, outstat1)

The output is unclear; however, this will be improved later.

Two-steps dimension reduction

Basis Expansion

This is an example of the two-step dimension reduction.

Generate radial basis function.

B1 = rbfunc(imagedim=img1$imagedim, seppix=2, hispec=FALSE, 
mask=img1$brainpos)

Multiplying the basis function to image data matrix.

SB1 = basisprod(img1$S, B1)

The original dimension was 6422.

dim(img1$S)
## [1]   40 6422

The dimension was reduced to 813.

dim(SB1)
## [1]  40 813

Principal Component Analysis

The Principal Component Analysis (PCA) is applied to the dimension-reduced image.

(fit211 = msma(SB1, comp=2))
## Call:
## msma.default(X = SB1, comp = 2)
## 
## Numbers of non-zeros for X: 
##        comp1 comp2
## block1   813   813
## 
## Numbers of non-zeros for X super: 
## comp1 comp2 
##     1     1

The loading is reconstructed to the original space by using the rec function.

Q = fit211$wbX[[1]][,1]
outstat1 = rec(Q, img1$imagedim, B=B1, mask=img1$brainpos)

The plotted (sign-flipping) loading is smoother than the one without the dimension reduction by the basis function.

outstat2 = -outstat1
coat(template, outstat2)

Sparse PCA

If lambdaX (>0) is specified, a sparse principal component analysis is implemented.

(fit112 = msma(SB1, comp=2, lambdaX=0.075))
## Call:
## msma.default(X = SB1, comp = 2, lambdaX = 0.075)
## 
## Numbers of non-zeros for X: 
##        comp1 comp2
## block1    37    28
## 
## Numbers of non-zeros for X super: 
## comp1 comp2 
##     1     1

The plotted loading is narrower than that from the PCA.

Q = fit112$wbX[[midx]][,vidx]
outstat1 = rec(Q, img1$imagedim, B=B1, mask=img1$brainpos)
outstat2 = outstat1
coat(template, outstat2)

The region is reported as follows to be compared with the next method.

atlastable(tmpatlas, outstat2, atlasdataset)
##    ROIid                  ROIname sizepct sumvalue   Min.   Mean Max.
## 56    56           Right Fusiform   0.948 -341.276 -7.779 -0.011    0
## 54    54 Right Inferior Occipital   1.000 -115.863 -6.967 -0.004    0
## 98    98       Right Cerebellum 6   1.000 -202.782 -6.858 -0.006    0
## 90    90  Right Inferior Temporal   0.887 -208.641 -6.634 -0.006    0
## 92    92         Right Cerebellum   1.000 -301.399 -6.442 -0.009    0
## 48    48            Right Lingual   1.000 -139.797 -4.917 -0.004    0
## 96    96     Right Cerebellum 4-5   1.000  -73.940 -4.708 -0.002    0
## 86    86    Right Middle Temporal   0.931 -116.613 -4.345 -0.004    0
## 40    40    Right Parahippocampus   0.860  -34.300 -3.412 -0.001    0
## 52    52   Right Middle Occipital   1.000  -33.213 -2.675 -0.001    0

Supervised Sparse PCA

The simbrain generates the synthetic brain image data and the binary outcome. The outcome Z is obtained.

Z = img1$Z

If the outcome Z is specified in the msma function, a supervised sparse principal component analysis is implemented.

(fit113 = msma(SB1, Z=Z, comp=2, lambdaX=0.075, muX=0.5))
## Call:
## msma.default(X = SB1, Z = Z, comp = 2, lambdaX = 0.075, muX = 0.5)
## 
## Numbers of non-zeros for X: 
##        comp1 comp2
## block1    40    38
## 
## Numbers of non-zeros for X super: 
## comp1 comp2 
##     1     1

The plotted loading is located differently from the sparse PCA.

Q = fit113$wbX[[1]][,1]
outstat1 = rec(Q, img1$imagedim, B=B1, mask=img1$brainpos)
outstat2 = -outstat1
coat(template, outstat2)

The region near the hippocampus, which differs from the sparse PCA (without supervision).

atlastable(tmpatlas, outstat2, atlasdataset)
##    ROIid                ROIname sizepct sumvalue Min.  Mean  Max.
## 37    37       Left Hippocampus   1.000  153.060    0 0.005 5.660
## 39    39   Left Parahippocampus   1.000  143.699    0 0.004 5.306
## 55    55          Left Fusiform   0.965  110.647    0 0.003 4.703
## 38    38      Right Hippocampus   1.000   75.242    0 0.002 3.683
## 73    73           Left Putamen   1.000   29.517    0 0.001 3.654
## 41    41          Left Amygdala   1.000   26.821    0 0.001 3.614
## 95    95    Left Cerebellum 4-5   1.000   42.869    0 0.001 3.585
## 40    40  Right Parahippocampus   1.000   90.091    0 0.003 3.462
## 89    89 Left Inferior Temporal   1.000   78.407    0 0.002 3.430
## 77    77          Left Thalamus   1.000   48.574    0 0.001 3.083

The loading for the second component

Q = fit113$wbX[[1]][,2]
outstat1 = rec(Q, img1$imagedim, B=B1, mask=img1$brainpos)
outstat2 = -outstat1
coat(template, outstat2)

atlastable(tmpatlas, outstat2, atlasdataset)
##    ROIid                  ROIname sizepct sumvalue   Min.   Mean Max.
## 56    56           Right Fusiform   0.948 -335.918 -7.904 -0.010    0
## 98    98       Right Cerebellum 6   1.000 -207.224 -7.112 -0.006    0
## 54    54 Right Inferior Occipital   1.000 -118.017 -7.083 -0.004    0
## 92    92         Right Cerebellum   1.000 -339.879 -6.865 -0.010    0
## 90    90  Right Inferior Temporal   0.887 -204.087 -6.495 -0.006    0
## 48    48            Right Lingual   1.000 -141.114 -5.258 -0.004    0
## 96    96     Right Cerebellum 4-5   1.000  -67.812 -4.432 -0.002    0
## 86    86    Right Middle Temporal   0.931 -110.785 -4.319 -0.003    0
## 40    40    Right Parahippocampus   0.860  -29.013 -3.012 -0.001    0
## 52    52   Right Middle Occipital   1.000  -32.460 -2.641 -0.001    0

This is similar to the result from the sparse PCA (without supervision).

The following method can be used to plot the weights of several components simultaneously. It is first reconstructed in three dimensions with the multirec function and then plotted with the multicompplot function. It is set to display four columns per component.

ws = multirec(fit113, imagedim=img1$imagedim, B=B1, 
mask=img1$brainpos)
multicompplot(ws, template, col4comp=4)