-
Notifications
You must be signed in to change notification settings - Fork 0
/
screestick.R
125 lines (107 loc) · 2.71 KB
/
screestick.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
screestick <- function(ev, las = 1, positive = TRUE,
evmean = FALSE, relative = FALSE)
{
# Description
# A function to draw a screeplot of a vector of eigenvalues
# with overlay of the values predicted by the broken stick model
#
# This function mimics the default output of function
# screeplot.cca {vegan} but it works on a vector of eigenvalues,
# which makes it independent of the function and package that has
# computed the ordination.
# Arguments
# ev vector of eigenvalues
# las orientation of the x axis labels
# ww width of bars in barplot
# ss space between bars in barplot
# evmean logical: should the mean of the eigenvalues be overlaid?
# relative logical: should the eigenvalues be divided by their
# sum to represent relative proportions of variation?
# Licence: GPL-2
# Author: Daniel Borcard
# September 2017
require(vegan)
if(is.vector(ev) == FALSE)
stop("Please provide a *vector* of eigenvalues", call. = FALSE)
evs <- sort(ev, decreasing = TRUE)
if(sum(abs(ev - evs)) > 0)
{
cat("The values were not in decreasing order. They have been sorted.\n")
}
if(positive == TRUE)
{
ntemp <- length(evs)
evs <- evs[evs > 0]
n <- length(evs)
if(ntemp > n)
{
cat("Warning: presence of", ntemp - n, "negative eigenvalues. \n")
cat("Only the", n, "positive eigenvalues are considered.\n")
}
}
else
{
n <- length(evs)
}
if(relative == TRUE)
{
evs <- evs/sum(evs)
}
names(evs) <- paste("EV", 1 : n)
# Broken stick model
broken <- bstick(n) * sum(evs)
if(relative == TRUE)
{
ylabel = "Relative eigenvalue"
}
else
{
ylabel = "Eigenvalue"
}
# Scree plot
barplot(evs,
ylim = c(0, max(c(evs, broken))),
main = "Eigenvalues and broken stick model",
ylab = ylabel,
las = las)
# Overlay the lines and points representing the broken stick model.
# The bars of the bar plot have width ww = 1 and are preceded and
# separated by an interval ss = 0.2. There are n bars. Argument
# 'absc' below is computed to ensure that the line breaks and the
# corresponding points of the broken stick model are aligned with
# the centers of the bars of the scree plot.
# ww and ss might be added as arguments in a later version.
ww <- 1
ss <- 0.2
ws <- ww + ss
n05 <- ww/2
absc <- seq((n05 + ss), ((n * ws) - n05), by = ws)
lines(
absc,
broken,
type = "o",
pch = 1,
col = "red"
)
if(evmean == TRUE)
{
abline (h = mean(evs), col = "darkgray")
legend(
"topright",
legend = c("Broken Stick", "Mean of eigenvalues"),
pch = c(1, NA_integer_),
lty = 1,
col = c("red", "gray"),
bty = "n")
}
else
{
legend(
"topright",
"Broken Stick",
pch = 1,
lty = 1,
col = "red",
bty = "n")
}
}