In this very synthetic tutorial, we will walk readers through different analyses and example of usages of the latest version of R package crqa() as they appear in Coco, et, al., (in press). Our goal is to provide readers with a reference guide to all analyses that are possible with crqa(). We refer readers to such a paper for greater details about the theoretical insights associated with these sets of analysis.
library(crqa) # The crqa() package
library(pracma) # To simulate data (sine waves) data(crqa) # Load the data available in the package options(scipen = 999) # Disable scientific notation
# Alpha colours for illustrating diagonal|windowed-crqa
diagcol = "#FF000080" # gray 80
windcol = "#36648B80" # gray 51
## The focus window for the text example (Figure 4)
xd = c(100, 0, 1800, 2000)
yd = c(0, 100, 2000, 2000)
xw = c(0, 0, 100, 100)
yw = c(0, 100, 100, 0)parC = list(unit = 200, labelx = "", labely = "",
cols = "black", pcex = .3, pch = 20, las = 0,
labax = seq(0, nrow(Figure_1), 200), labay = seq(0, nrow(Figure_1), 200)) par(mfrow = c(1, 3), font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plot(Figure_1$sinus, type = "l", xlab = "", ylab = "", axes = F, lwd = 2)
box()
plot(Figure_1$lorenz, type = "l", xlab = "", ylab = "", axes = F, lwd = 2)
box()
plot(Figure_1$wnoise, type = "l", xlab = "", ylab = "", axes = F, lwd = 2)
box()SINrqa1 <- crqa(ts1 = Figure_1$sinus, ts2 = Figure_1$sinus, delay = 1,
embed = 1, rescale = 0, radius = 0.03, normalize = 0,
side = 'both', method = 'rqa', datatype = 'continuous')
LORrqa1 <- crqa(ts1 = Figure_1$lorenz, ts2 = Figure_1$lorenz, delay = 1,
embed = 1, rescale = 0, radius = 0.03, normalize = 0,
side = 'both', method = 'rqa', datatype = 'continuous')
WNOISErqa1 <- crqa(ts1 = Figure_1$wnoise, ts2 = Figure_1$wnoise, delay = 1,
embed = 1, rescale = 0, radius = 0.003, normalize = 0,
side = 'both', method = 'rqa', datatype = 'continuous')
par(mfrow = c(1,3), font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5,
mar = c(1, 5.5, 3, 2), oma = c(1,1,2,1))
plotRP(SINrqa1$RP, parC)
plotRP(LORrqa1$RP, parC)
plotRP(WNOISErqa1$RP, parC)SINrqa2 <- crqa(ts1 = Figure_1$sinus, ts2 = Figure_1$sinus, delay = 110,
embed = 2, rescale = 0, radius = 0.02, normalize = 0,
side = 'both', method = 'rqa', datatype = 'continuous')
LORrqa2 <- crqa(ts1 = Figure_1$lorenz, ts2 = Figure_1$lorenz, delay = 10,
embed = 3, rescale = 0, radius = 1.3, normalize = 0,
side = 'both', method = 'rqa', datatype = 'continuous')
WNOISErqa2 <- crqa(ts1 = Figure_1$wnoise, ts2 = Figure_1$wnoise, delay = 1,
embed = 3, rescale = 0, radius = 0.1, normalize = 0,
side = 'both', method = 'rqa', datatype = 'continuous')
par(mfrow = c(1,3), font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5,
mar = c(1, 5.5, 3, 2), oma = c(1,1,2,1))
## The sinusoid has a longer delay, so we need to change the label to reflect this
parC$labax = seq(0, 1000, 200); parC$labay = seq(0,1000, 200)
plotRP(SINrqa2$RP, parC)
parC$labax = seq(0, 1200, 200); parC$labay = seq(0,1200, 200)
plotRP(LORrqa2$RP, parC)
plotRP(WNOISErqa2$RP, parC)Figure_2 = as.numeric(as.matrix(Figure_2)) # Make it a vectorpar(font.lab = 2, font.axis = 2, cex.lab = 1.7, cex.axis = 1.5)
plot(Figure_2[1:42], Figure_2[4:45], type = 'b',
las = 1, xlab = 'dimension 1', ylab = 'dimension 2',
main = '', lwd = 2)
points(Figure_2[1], Figure_2[4], pch = 19, cex = 1.2, col = "blue")
points(Figure_2[6], Figure_2[9], pch = 19, cex = 1.2, col = "green")
points(Figure_2[9], Figure_2[12], pch = 19, cex = 1.2, col = "red")
symbols(x = Figure_2[9], y = Figure_2[12], circles = 0.25, add = TRUE,
inches = FALSE)
points(Figure_2[24], Figure_2[27], pch = 19, cex = 1.2, col = "red")
points(Figure_2[38], Figure_2[41], pch = 19, cex = 1.2, col = "red")
points(Figure_2[39], Figure_2[42], pch = 19, cex = 1.2, col = "red")
text(x = -0.5, y = -1.1, labels = "Threshold", adj = 1)
text(x = -0.6, y = -0.2, adj = 0,
label = "Recurrences of the point")
text(x = -0.6, y = -0.3, adj = 0,
bquote('('~X[9]*';'~X[9+tau]*')'))par(font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plot(Figure_2, 45:1, type = 'b', las = 1, xlab = "", ylab = "time",
yaxt = "n")
points(Figure_2[1], 45, pch = 19, cex = 1.2, col = "blue")
points(Figure_2[6], 40, pch = 19, cex = 1.2, col = "green")
points(Figure_2[9], 37, pch = 19, cex = 1.2, col = "red")
axis(side = 2, at = seq(from = 45, to = 5, by = -10), las = 1,
labels = c(0, 10, 20, 30, 40), tick = T)par(font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plot(Figure_2[4:45], type = 'b', las = 1, xlab = 'time', ylab = '')
points(1, Figure_2[4], pch = 19, cex = 1.2, col = "blue")
points(6, Figure_2[9], pch = 19, cex = 1.2, col = "green")
points(9, Figure_2[12], pch = 19, cex = 1.2, col = "red")fig2rqa <- crqa(ts1 = Figure_2, ts2 = Figure_2, delay = 3, embed = 2,
radius = 0.25, method = 'rqa', datatype = 'continuous')
parC$unit = 10; parC$labax = ""; parC$labay = ""; parC$pcex = 1; parC$pch = 15
par(font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plotRP(fig2rqa$RP, parC)
ixi_9 = which(fig2rqa$RP[9,] == T)
points(rep(9, length(ixi_9)), ixi_9, col = "red", pch = 15, cex = 1)
points(ixi_9, rep(9, length(ixi_9)), col = "red", pch = 15, cex = 1)par(mfrow = c(1,2), font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5,
mar = c(4.5, 4.5, 1, 1))
L1 <- Figure_3[,1]
L2 <- Figure_3[,2]
# Panel A.
plot(L2, type = "l", xlab = "time", ylab = "", lwd = 2)
lines(L1, col = "red", lwd = 2)
# Panel B
# Run DCRP analysis on data
Fig3 <- drpfromts(ts1 = L2, ts2 = L1, delay = 1, embed = 1,
windowsize = 20, radius = 0.02, datatype = "continuous",
rescale = 0, normalize = 0, mindiagline = 2,
minvertline = 2, tw = 0, side = 'both', method = "crqa")
# Plot the recurrence profile
plot(-20:20, Fig3$profile, type = "b",
lwd = 2, ylab = "Recurrence Rate", xlab = "Lag", cex = 0.8)
abline(v = 0, lty = 2)## Setting the parameters
delay = 1; embed = 1; rescale = 0; radius = 0.0001;
normalize = 0; mindiagline = 2; minvertline = 2;
tw = 1; whiteline = FALSE; recpt = FALSE;
side = "both"; method = 'rqa'; metric = 'euclidean';
datatype = "categorical"
## Run the analysis
ans = crqa(text, text, delay, embed, rescale, radius, normalize,
mindiagline, minvertline, tw, whiteline, recpt, side, method, metric,
datatype)
#> Warning in crqa(text, text, delay, embed, rescale, radius, normalize,
#> mindiagline, : Your input data was provided either as character or factor, and
#> recoded as numerical identifiers
## Update plotting arguments
parC = list(unit = 10, labelx = "Time", labely = "Time",
cols = "black", pcex = .5, pch = 15, las = 0,
labax = seq(0, nrow(ans$RP), 10), labay = seq(0, nrow(ans$RP), 10))
## Generate the plot
par(font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plotRP(ans$RP, parC)
rect(81, 81, 110, 110, border = "red", lwd = 2)text_zoom = text[81:110]
ans_zoom = crqa(text_zoom, text_zoom, delay, embed, rescale, radius, normalize,
mindiagline, minvertline, tw, whiteline, recpt, side, method, metric,
datatype)
#> Warning in crqa(text_zoom, text_zoom, delay, embed, rescale, radius,
#> normalize, : Your input data was provided either as character or factor, and
#> recoded as numerical identifiers
# Add to the graphics parameters the labels for the axes (x,y)
parC$labay = parC$labax = text_zoom
# Change the las argument to print the words vertically
parC$las = 2 # make it vertical
# Change the unit to make it word by word
parC$unit = 1 # make it vertical
# Change the label of x, y axis
parC$labelx = parC$labely = "Words"
par(font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plotRP(ans_zoom$RP, parC)listener = eyemovement$listener
narrator = eyemovement$narrator
delay = 1; embed = 1; rescale = 0; radius = .01;
normalize = 0; mindiagline = 2; minvertline = 2;
tw = 0; whiteline = FALSE; recpt = FALSE; side = "both"
method = 'crqa'; metric = 'euclidean';
datatype = "categorical"
## Compute cross-recurrence quantification analysis
ans = crqa(narrator, listener, delay, embed, rescale, radius, normalize,
mindiagline, minvertline, tw, whiteline, recpt, side, method, metric,
datatype)
## Uncomment to check performance (but need to load profvis)
# pf = profvis(crqa(narrator, listener, delay, embed, rescale, radius, normalize,
# mindiagline, minvertline, tw, whiteline, recpt, side, method, metric,
# datatype))
RP = as.matrix(ans$RP)
results = unlist(ans[1:10])
## Change again the plotting parameters
parC$labelx = parC$labely = "Time (sec.)"
parC$unit = 333 ## in ms
parC$pcex = .1 # make this much smaller as we have loads of points
parC$labax = parC$labay = seq(0, 60, 10)
parC$las = 1
windowstep = 50par(font.lab = 2, font.axis = 2, cex.lab = 2, cex.axis = 1.5)
plotRP(RP, parC)
polygon(xd, yd, col = diagcol, border = F) # the diagonal
polygon(xw, yw, col = windcol, border = F) # the first window
for (w in 1:10){ # the number of overlapping windows that we want to plot
polygon(xw + windowstep, yw + windowstep, col = windcol, border = F) # # the second window
polygon(xw + w*windowstep, yw + w*windowstep, col = windcol, border = F) # the third window
polygon(xw + w*windowstep, yw + w*windowstep, col = windcol, border = F) # the fourth window
}## Construct the time-course for the diagonal profile
timecourse = round( seq(-3300,3300,33)/1000, digit = 2)
## Show diagonal-profile CRQA with eye-movement data
res = drpfromts(narrator, listener, windowsize = 100,
radius = 0.001, delay = 1, embed = 1, rescale = 0,
normalize = 0, mindiagline = 2, minvertline = 2,
tw = 0, whiteline = F, recpt = F, side = 'both',
method = 'crqa', metric = 'euclidean',
datatype = 'continuous')
profile = res$profile*100
par(font.lab = 2, font.axis = 2, cex.lab = 1.8, cex.axis = 1.3,
mar = c(4.5, 5.5, 1, 2))
plot(timecourse, profile, type = "l", lwd = 2.5, xlab = "Lag (seconds)",
ylab = "Recurrence Rate %")delay = 1; embed = 1; rescale = 1; radius = 0.001;
normalize = 0; mindiagline = 2; minvertline = 2;
tw = 0; whiteline = FALSE; recpt = FALSE; side = "both"
method = 'crqa'; metric = 'euclidean';
datatype = "categorical"; windowsize = 100;
lagwidth = 50; windowstep = 20
## Calculate windowed cross-recurrence
res = windowdrp(narrator, listener, windowstep, windowsize, lagwidth,
radius = 0.001, delay = 1, embed = 1, rescale = 0,
normalize = 0, mindiagline = 2, minvertline = 2,
tw = 0, whiteline = F, side = 'both',
method = 'crqa', metric = 'euclidean',
datatype = "continuous")
profile = res$profile*100
timecourse = round( seq(1, length(profile), 1)*windowstep*.033, digit = 1)
par(font.lab = 2, font.axis = 2, cex.lab = 1.8, cex.axis = 1.3,
mar = c(4.5, 5.5, 1, 2))
plot(timecourse, profile, type = "l", lwd = 2.5,
xlab = "Time (seconds)", ylab = "Recurrence Rate %")listener = eyemovement$listener
narrator = eyemovement$narrator
delay = 1; embed = 1; rescale = 0; radius = 0.001;
normalize = 0; mindiagline = 2; minvertline = 2;
tw = 0; whiteline = FALSE; recpt = FALSE; side = "both"
method = 'crqa'; metric = 'euclidean';
datatype = "continuous";
windowsize = 100; windowstep = 20
trend = FALSE
ans = wincrqa(listener, narrator, windowstep, windowsize, delay, embed,
radius, rescale, normalize, mindiagline, minvertline,
tw, whiteline, recpt, side, method, metric,
datatype, trend)
profile = as.numeric(ans$RR)
plot(profile, type = 'l')# Reduce the dimensionality of the time series to reduce runtime
# handset = handmovement[1:3000, ]
handset = handmovement[1:1000, ]
P1 = cbind(handset$P1_TT_d, handset$P1_TT_n)
P2 = cbind(handset$P2_TT_d, handset$P2_TT_n)
delay = 5; embed = 2; rescale = 0; radius = .1;
normalize = 0; mindiagline = 10; minvertline = 10;
tw = 0; whiteline = FALSE; recpt = FALSE; side = "both"
method = 'mdcrqa'; metric = 'euclidean';
datatype = "continuous"
ans = crqa(P1, P2, delay, embed, rescale, radius, normalize,
mindiagline, minvertline, tw, whiteline, recpt, side, method, metric,
datatype)
RP = ans$RP
results = unlist(ans[1:10])
print(results)
#> RR DET NRLINE maxL L ENTR
#> 19.6643519 75.4671721 4024.0000000 161.0000000 36.5111829 3.7221108
#> rENTR LAM TT catH
#> 0.7408836 83.9759197 23.3335028 NA
## Adjust the plotting parameters
parC$unit = 300
parC$pcex = .1 # make this much smaller as we have loads of points
parC$labax = parC$labay = seq(0, nrow(RP), parC$unit)
plotRP(RP, parC)## Estimate parameters for uni-dimensional RQA using simulated data generated off sinusoids.
ts1 = seq(0.1, 200, .1)
ts1 = sin(ts1) + linspace(0, 1,length(ts1));
ts2 = ts1
par = list(method = "rqa", metric = "euclidean", maxlag = 20,
radiusspan = 100, radiussample = 40, normalize = 0,
rescale = 4, mindiagline = 10, minvertline = 10, tw = 0,
whiteline = FALSE, recpt = FALSE, side = "both",
datatype = "continuous", fnnpercent = 10, typeami = 'mindip')
results = optimizeParam(ts1, ts2, par, min.rec = 2, max.rec = 5) # it may take some time
print(unlist(results))
#> radius emddim delay
#> 0.1755553 2.0000000 18.0000000
ans = crqa(ts1, ts2, delay = results$delay, embed = results$emddim,
rescale, radius = results$radius)
unlist(print(ans[1:10]))
#> $RR
#> [1] 2.028753
#>
#> $DET
#> [1] 99.39771
#>
#> $NRLINE
#> [1] 7127
#>
#> $maxL
#> [1] 1982
#>
#> $L
#> [1] 11.11492
#>
#> $ENTR
#> [1] 2.666816
#>
#> $rENTR
#> [1] 0.7181268
#>
#> $LAM
#> [1] 97.9861
#>
#> $TT
#> [1] 3.205311
#>
#> $catH
#> [1] NA
#> RR DET NRLINE maxL L ENTR
#> 2.0287532 99.3977113 7127.0000000 1982.0000000 11.1149151 2.6668157
#> rENTR LAM TT catH
#> 0.7181268 97.9860972 3.2053113 NALet optimize parameters of multi-dimensional data using the hand-movements.
## Change a few parameters to set this
par$method = "mdcrqa";par$fnnpercent = NA; par$typeami = NA;
par$nbins = 50; par$criterion = "firstBelow"; par$threshold = 1.6;
par$maxEmb = 20; par$numSamples = 500; par$Rtol = 10; par$Atol = 2
results = optimizeParam(P1, P2, par, min.rec = 2, max.rec = 5) # it may take some time
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
#> Warning in sqrt((temp[yRd1[j]] - r2d[j])/r2d[j]): NaNs produced
print(unlist(results))
#> radius emddim delay
#> 0.04152206 4.00000000 2.00000000
ans = crqa(P1, P2, delay = results$delay, embed = results$emddim,
rescale, radius = results$radius, normalize,
mindiagline, minvertline, tw, whiteline, recpt, side, method, metric,
datatype)
print(ans[1:10])
#> $RR
#> [1] 9.457348
#>
#> $DET
#> [1] 80.5687
#>
#> $NRLINE
#> [1] 3136
#>
#> $maxL
#> [1] 87
#>
#> $L
#> [1] 24.0067
#>
#> $ENTR
#> [1] 3.417769
#>
#> $rENTR
#> [1] 0.7965975
#>
#> $LAM
#> [1] 91.88695
#>
#> $TT
#> [1] 31.73394
#>
#> $catH
#> [1] NAnbins = 10; maxlag = 10; criterion = "firstBelow"; threshold = exp(-1)
data(crqa) ## load the data
handset = handmovement[1:300, ] ## take less points
mdDelay(handset, nbins, maxlag, criterion, threshold)
#> [1] 2tau = 1; maxEmb = 10; numSamples = 500; Rtol = 10; Atol = 2
mdFnn(handset, tau, maxEmb, numSamples, Rtol, Atol)
#> $fnnPerc
#> [1] 100.000000 4.123711 2.749141 2.405498 3.780069 4.467354
#> [7] 4.810997 4.123711 4.810997 4.467354
#>
#> $embTimes
#> [1] 1 2 3 4 5 6 7 8 9 10YLIM = range(Figure_6$speed)
YLIM2 = range(Figure_6$memory)
perfFull = subset(Figure_6, Figure_6$typeRQA == "full")
perfPiece = subset(Figure_6, Figure_6$typeRQA == "piece")
sizes = unique(perfPiece$blocksize)
## Assign PCH to blocksize so that I can plot it
perfPiece$pch = apply(data.frame(perfPiece$blocksize),1,function(x) which(x == sizes))
colors = rainbow(length(sizes))
## Assign the color palette to the block size
perfPiece$colors = apply(data.frame(perfPiece$blocksize), 1, function(x){
ixi = which(x == sizes)
x = colors[ixi]})plot(perfPiece$datapoint, perfPiece$speed, type = "p", col = perfPiece$colors,
cex = 2.1, xlab = "Number of Data Points", pch = perfPiece$pch,
ylab = "Time (sec)", ylim = YLIM, main = "Speed")
points(perfFull$datapoint, perfFull$speed, type = "p", col = "black",
pch = 19, cex = 2.1)plot(perfPiece$datapoint, perfPiece$memory, type = "p", col = perfPiece$colors,
cex = 2.1, xlab = "Number of Data Points", pch = perfPiece$pch,
ylab = "Max Memory (Mb)", ylim = YLIM2, main = "Memory")
points(perfFull$datapoint, perfFull$memory, type = "p", col = "black",
pch = 19, cex = 2.1)
legend("topleft",legend = c(unique(perfPiece$blocksize), "full"),
col = c(unique(perfPiece$colors), "black"), cex = 1.5,
pch = c(unique(perfPiece$pch), 19), bty = "n")Coco, Monster, Leonardi, Dale & Wallot (in press). Unidimensional and Multidimensional Methods for Recurrence Quantification Analysis with crqa(). The R Journal.