You are on page 1of 36

Anlisis multivariante en R: aplicacin en ecologa

Rosana Ferrero
5 de febrero de 2014

ndice
1. Anlisis cluster con R: datos de peces (ambos mtodos).
1.1. Anlisis jerrquico . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1. PASO 1. Eleccin de variables (o casos) . . . . . . . . . . .
1.1.2. PASO 2. Eleccin de la tcnica cluster . . . . . . . . . . . .
1.1.3. PASO 3: Determinar el nmero de conglomerados finales
1.1.4. PASO 4. Representacin e interpretacin de los resultados
1.2. Anlisis no jerrquico . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1. Particin por k-medias . . . . . . . . . . . . . . . . . . . . .
1.2.2. k-medoides (PAM) . . . . . . . . . . . . . . . . . . . . . . .
1.3. PLUS: Anlisis extra para mejorar la interpretacin y validacin.
1.3.1. Comparacin con datos ambientales. . . . . . . . . . . . .
1.3.2. Ensables de especies . . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

2
2
2
3
6
11
12
12
15
21
21
28

1.

Anlisis cluster con R: datos de peces (ambos mtodos).

Anlisis cluster jerrquico y no jerrquico para datos de abundancia de peces a lo largo del ro Doubs
(francs-suizo) obtenidos por Verneaux (1973) y las caractersticas ambientales del sitio. Se quiere analizar:
a) Si existen distintos ensambles de peces a lo largo del cauce del ro. b) Cmo los cambios ambientales
registrados en el ro se relacionan con los cambios en la estructura de los ensambles de peces. Tenemos
30 filas (sitios), 27 especies de peces (columnas del archivo spe), 11 variables ambientales (columnas del
archivo env) y las coordenadas espaciales de los sitios (columnas del archivo spa). Para obtener ms detalles
de los datos puedes preguntar en R sobre los datos doubs del paquete ade4.

1.1.

Anlisis jerrquico

# --------- Anlisis jerrquico --------# cargamos los paquetes que vamos a necesitar (activar vegan luego de
# ade4 para evitar conflictos)
library(ade4)
library(vegan)
library(gclus)
library(cluster)
library(RColorBrewer)
library(labdsv)
library(mvpart)
library(MVPARTwrap)
## Warning: replacing previous import ccawhen loading de4
# cargamos algunas funciones que hemos de necesitar (los archivos
# deben estar en nuestro directorio de trabajo)
source("hcoplot.R")
source("test.a.R")
source("coldiss.R")

1.1.1.

PASO 1. Eleccin de variables (o casos)

# PASO 1. Eleccin de variables (o casos) importamos los archivos de


# datos (csv) (los archivos deben estar en nuestro directorio de
# trabajo)
spe <- read.csv("DoubsSpe.csv", row.names = 1)
env <- read.csv("DoubsEnv.csv", row.names = 1)
spa <- read.csv("DoubsSpa.csv", row.names = 1)
# Remove empty site 8
spe <- spe[-8, ]
env <- env[-8, ]
spa <- spa[-8, ]
# estandarizamos los datos
spe.norm <- decostand(spe, "normalize")

1.1.2.

PASO 2. Eleccin de la tcnica cluster

# PASO 2. Eleccin de la tcnica cluster I) Anlisis de conglomerados


# jerrquico de los datos de abundancias de especies --# ------ Determinar qu mtodo de conglomerado es el mejor ---# calculamos la matriz de distancias
spe.ch <- vegdist(spe.norm, "euc")
# calculamos el cluster por varios mtodos para elegir luego el ms
# adecuado
par(mfrow = c(2, 3)) #para disponer juntos los grficos
# Mtodo single
spe.ch.single <- hclust(spe.ch, method = "single")
plot(spe.ch.single) # graficamos el dendrograma
# Mtodo complete
spe.ch.complete <- hclust(spe.ch, method = "complete")
plot(spe.ch.complete)
# Mtod UPGMA
spe.ch.UPGMA <- hclust(spe.ch, method = "average")
plot(spe.ch.UPGMA)
# Mtodo centroid
spe.ch.centroid <- hclust(spe.ch, method = "centroid")
plot(spe.ch.centroid)
# Mtodo de mnima varianza de Ward
spe.ch.ward <- hclust(spe.ch, method = "ward")
plot(spe.ch.ward)
# transformacin de la raz cuadrada
spe.ch.ward$height <- sqrt(spe.ch.ward$height)
plot(spe.ch.ward)

# Correlaciones cofenticas ------# Single


spe.ch.single.coph <- cophenetic(spe.ch.single)
cor(spe.ch, spe.ch.single.coph)
## [1] 0.5992
# Complete
spe.ch.comp.coph <- cophenetic(spe.ch.complete)
cor(spe.ch, spe.ch.comp.coph)
## [1] 0.7656
3

# Average
spe.ch.UPGMA.coph <- cophenetic(spe.ch.UPGMA)
cor(spe.ch, spe.ch.UPGMA.coph)
## [1] 0.8608
# Ward
spe.ch.ward.coph <- cophenetic(spe.ch.ward)
cor(spe.ch, spe.ch.ward.coph)
## [1] 0.7985
cor(spe.ch, spe.ch.ward.coph, method = "spearman")
## [1] 0.7661
# el mayor coeficiente de correlacin cofentica corresponde al
# mtodo UPGMA
# Diagrama de Shepard ---- Para ilustrar las relaciones entre la
# matriz de distancias original y la matriz de distancias cofentica
par(mfrow = c(2, 2))
plot(spe.ch, spe.ch.single.coph, xlab = "Chord distance", ylab = "Cophenetic distance",
asp = 1, xlim = c(0, sqrt(2)), ylim = c(0, sqrt(2)), main = c("Single linkage",
paste("Cophenetic correlation =", round(cor(spe.ch, spe.ch.single.coph),
3))))
abline(0, 1)
lines(lowess(spe.ch, spe.ch.single.coph), col = "red")
plot(spe.ch, spe.ch.comp.coph, xlab = "Chord distance", ylab = "Cophenetic distance",
asp = 1, xlim = c(0, sqrt(2)), ylim = c(0, sqrt(2)), main = c("Complete linkage",
paste("Cophenetic correlation =", round(cor(spe.ch, spe.ch.comp.coph),
3))))
abline(0, 1)
lines(lowess(spe.ch, spe.ch.comp.coph), col = "red")
plot(spe.ch, spe.ch.UPGMA.coph, xlab = "Chord distance", ylab = "Cophenetic distance",
asp = 1, xlim = c(0, sqrt(2)), ylim = c(0, sqrt(2)), main = c("UPGMA",
paste("Cophenetic correlation =", round(cor(spe.ch, spe.ch.UPGMA.coph),
3))))
abline(0, 1)
lines(lowess(spe.ch, spe.ch.UPGMA.coph), col = "red")
plot(spe.ch, spe.ch.ward.coph, xlab = "Chord distance", ylab = "Cophenetic distance",
asp = 1, xlim = c(0, sqrt(2)), ylim = c(0, max(spe.ch.ward$height)),
main = c("Ward clustering", paste("Cophenetic correlation =", round(cor(spe.ch,
spe.ch.ward.coph), 3))))
abline(0, 1)
lines(lowess(spe.ch, spe.ch.ward.coph), col = "red")
# Distancia de Gower (1983) -----(gow.dist.single <- sum((spe.ch - spe.ch.single.coph)^2))
## [1] 95.41
(gow.dist.comp <- sum((spe.ch - spe.ch.comp.coph)^2))
4

## [1] 40.49
(gow.dist.UPGMA <- sum((spe.ch - spe.ch.UPGMA.coph)^2))
## [1] 11.67
(gow.dist.ward <- sum((spe.ch - spe.ch.ward.coph)^2))
## [1] 532
# segn la distancia de Gower, el mejor mtodo es UPGMA
# por tanto, seleccionaramos los resultados del mtodo UPGMA sin
# embargo, para comparar el mtodo con anlisis posteriores, aqu
# vamos a seleccionar el mtodo Ward

1.2
1.0

1
9

spe.ch
hclust (*, "complete")

spe.ch
hclust (*, "average")

Cluster Dendrogram

Cluster Dendrogram

Cluster Dendrogram

1
15
16
19
17
18
2
3
7
10
4
6
13
14
11
12

5
9

UPGMA
Cophenetic correlation = 0.861

Ward clustering
Cophenetic correlation = 0.799

1.0
0.0

1.2
0.8
0.4

2.0

Chord distance

Cophenetic distance

Chord distance

Chord distance

1.1.3.

20
21
22
26
27
28
29
30
25
23
24

1.2
0.8
0.4
0.0

0.0

1.5

Height

spe.ch
hclust (*, "ward")

Complete linkage
Cophenetic correlation = 0.766
Cophenetic distance

1.2
0.8
0.4
0.0

Cophenetic distance
Cophenetic distance

1.0

spe.ch
hclust (*, "ward")

Single linkage
Cophenetic correlation = 0.599

0.5

20
21
22
26
27
28
29
30
25
23
24
5
9
15
16
19
17
18
2
3
7
10
4
6
1
13
14
11
12

3
7
2

spe.ch
hclust (*, "centroid")

0.0

Height

11
13
14
6
4
12

20
30
26
29
21
22
27
28
17
18

25
23
24
15
10

19

16

9
5

0.5
0.1

0.3

Height

2.0

0.7

2.5

spe.ch
hclust (*, "single")

17
18

26
27
28
29
21
22

13
14
4
6
12
2
3
7

11

15
16
19

10

25
23
24

Height

0.6
20
30

0.2

0.2

12
2
3
7
11
13
14
15
16
10
4
6
19
17
18
29
30
20
21
22
26
27
28
25
23
24

0.4

1
0.6

23
24
12
4
6
2
3
7

13
14

30
20
21
22
29
26
27
28
17
18

11

19

16
15
10

25

Height

0.8

1.0

5
1

0.6
0.4
0.2

Height

Cluster Dendrogram

1.4

Cluster Dendrogram

0.8

Cluster Dendrogram

0
Chord distance

PASO 3: Determinar el nmero de conglomerados finales

# PASO 3: Determinar el nmero de conglomerados finales Podemos


# seleccionarlo de manera subjetiva mediante el examen visual del

# dendrograma, o podemos elegir un criterio ms objetivo para


# predeterminar el nmero de cluster a retener.
# ------# Seleccionar el nmero de conglomerados final ------#
# Grfico de nivel de fusin ------------ Ward
plot(spe.ch.ward$height, nrow(spe):2, type = "S", main = "Fusion levels - Chord - Ward",
ylab = "k (number of clusters)", xlab = "h (node height)", col = "grey")
text(spe.ch.ward$height, nrow(spe):2, nrow(spe):2, col = "red", cex = 0.8)
# Nmero ptimo de cluster segn el ancho de silueta -------# (Rousseeuw quality index)
# graficamos el ancho medio de silueta para todas las particiones,
# excepto para la trivial (k=1) creamos un vector nulo para ir
# agregando los valores
asw <- numeric(nrow(spe))
# creamos un loop para los clculos
for (k in 2:(nrow(spe) - 1)) {
sil <- silhouette(cutree(spe.ch.ward, k = k), spe.ch)
asw[k] <- summary(sil)$avg.width
}
k.best <- which.max(asw)
# graficamos

plot(1:nrow(spe), asw, type = "h", main = "Silhouette-optimal number of clusters, Ward",


xlab = "k (number of groups)", ylab = "Average silhouette width")
axis(1, k.best, paste("optimum", k.best, sep = "\n"), col = "red", font = 2,
col.axis = "red")
points(k.best, max(asw), pch = 16, col = "red", cex = 1.5)
cat("", "Silhouette-optimal number of clusters k =", k.best, "\n", "with an average silhouette width of"
max(asw), "\n")
##
##

Silhouette-optimal number of clusters k = 2


with an average silhouette width of 0.3658

# segn este criterio se deben seleccionar 2 clusters (k=2), sin


# embargo, por razones ecolgicas, resulta ms interesante formar 4
# particiones
# Estadstico de Mantel (Pearson) ----------------------# Creamos una funcin para calcular la matriz de distancia binaria
# con los grupos
grpdist <- function(X) {
require(cluster)
gr <- as.data.frame(as.factor(X))
distgr <- daisy(gr, "gower")
distgr
}
# calculamos el estadsticos para el mtodo de Ward
7

kt <- data.frame(k = 1:nrow(spe), r = 0)


for (i in 2:(nrow(spe) - 1)) {
gr <- cutree(spe.ch.ward, i)
distgr <- grpdist(gr)
mt <- cor(spe.ch, distgr, method = "pearson")
kt[i, 2] <- mt
}
kt
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

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

k
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

r
0.0000
0.6554
0.7081
0.7155
0.6429
0.6741
0.6865
0.6879
0.6926
0.6499
0.6464
0.6396
0.6304
0.5009
0.4960
0.4375
0.4027
0.3950
0.3852
0.3571
0.3424
0.3271
0.3111
0.2931
0.2512
0.1971
0.1615
0.1149
0.0000

k.best <- which.max(kt$r)


# graficamos
plot(kt$k, kt$r, type = "h", main = "Mantel-optimal number of clusters - Ward",
xlab = "k (number of groups)", ylab = "Pearsons correlation")
axis(1, k.best, paste("optimum", k.best, sep = "\n"), col = "red", font = 2,
col.axis = "red")
points(k.best, max(kt$r), pch = 16, col = "red", cex = 1.5)
cat("", "Mantel-optimal number of clusters k =", k.best, "\n", "with a matrix linear correlation of",
max(kt$r), "\n")
##
##

Mantel-optimal number of clusters k = 4


with a matrix linear correlation of 0.7155

# este criterio selecciona como ptimo el formar 4 conglomerados o


# clusters (k=4).
8

30

Fusion levels Chord Ward

20
15

19
18
17
16
15
14
13
12
11

10

k (number of clusters)

25

29
28
27
26
25
24
23
22
21
20

10
9
8
7
6

5
4
3
2

0.5

1.0

1.5

2.0

2.5

h (node height)

0.2
0.1
0.0

Average silhouette width

0.3

Silhouetteoptimal number of clusters, Ward

optimum
2

10

15
k (number of groups)

20

25

30

0.5
0.4
0.3
0.2
0.0

0.1

Pearson's correlation

0.6

0.7

Manteloptimal number of clusters Ward

optimum
4 5

10

15

20

25

k (number of groups)

Validacin final
# Validacin final Grfico de silueta para la particin final
# -------- Vemos si los miembros de los grupos estn bien
# clasificados
# para 4 clusters
k <- 4
# graficamos la silueta
cutg <- cutree(spe.ch.ward, k = k)
sil <- silhouette(cutg, spe.ch)
rownames(sil) <- row.names(spe)
plot(sil, main = "Silhouette plot - Chord - Ward", cex.names = 0.8, col = 2:(k +
1), nmax = 100)
# los grupos 1 y 3 son bastante coherentes, mientras que el grupo 2
# contiene algunos miembros mal clasificados

10

30

Silhouette plot Chord Ward


4 clusters Cj
j : nj | aveiCj si

n = 29
2
3
12
7
11
13
4
14
1
6
10
17
16
9
18
5
19
15
21
22
27
29
28
30
26
20
23
24
25

1 : 11 | 0.37

2 : 7 | 0.04

3 : 8 | 0.60

4 : 3 | 0.34

0.0

0.2

0.4

0.6

0.8

Silhouette width si
Average silhouette width : 0.35

1.1.4.

PASO 4. Representacin e interpretacin de los resultados

# PASO 4. Representacin e interpretacin de los resultados Agregar


# colores a los grupos hcoplot(spe.ch.ward, spe.ch, k=4)
# Grfico con mapa del ro Doubs (para datos espacialmente
# explcitos) ----plot(spa, asp = 1, type = "n", main = "Four Ward clusters along the Doubs river",
xlab = "x coordinate (km)", ylab = "y coordinate (km)")
lines(spa, col = "light blue")
text(50, 10, "Upstream", cex = 1.2)
text(25, 115, "Downstream", cex = 1.2)
# Add the four groups
spebc.ward.g <- cutree(spe.ch.ward, k = 4)
grw <- spebc.ward.g
k <- length(levels(factor(grw)))
for (i in 1:k) {
points(spa[grw == i, 1], spa[grw == i, 2], pch = i + 20, cex = 3, col = i +
1, bg = i + 1)
}
text(spa, row.names(spa), cex = 0.8, col = "white", font = 2)
legend("bottomright", paste("Cluster", 1:k), pch = (1:k) + 20, col = 2:(k +
1), pt.bg = 2:(k + 1), pt.cex = 2, bty = "n")

11

1.0

Four Ward clusters along the Doubs river


24
25

23

200

22
21
20 19

26

16

15
13

28

150

17

14

27

y coordinate (km)

18

29

12

30

11

Downstream
100

10
9

50

7
6

Upstream
100

Cluster 1
Cluster 2
Cluster 3
Cluster 4

5
4
3

100

200

300

x coordinate (km)

1.2.

Anlisis no jerrquico

1.2.1.

Particin por k-medias

#
#
#
#
#

Particin por k-medias El criterio de particin de k-medias es


similar al del mtodo de Ward, ya que el mtodo iterativamente
minimiza el total del error de la suma de cuadrados. Es un mtodo
lineal, por loque no es apropiado para datos de abundancias de
especies con muchos ceros.

# con 4 grupos
set.seed(1)
spe.kmeans <- kmeans(spe.norm, centers = 4, nstart = 100)
# Comparacin con la clasificacin de Ward con 4 grupos
table(spe.kmeans$cluster, spebc.ward.g)
##
##
##
##
##
##

spebc.ward.g
1 2 3 4
1 0 0 0 3
2 11 1 0 0
3 0 6 0 0
4 0 0 8 0

# vemos que solo se diferencian en la clasificacin de 1 caso.


# Cul es el mejor nmero de clusters a retener? ---- calculamos
# particiones desde 2 a 10 clusters
spe.KM.cascade <- cascadeKM(spe.norm, inf.gr = 2, sup.gr = 10, iter = 100,
12

criterion = "ssi")
summary(spe.KM.cascade)
##
##
##
##
##

Length
partition 261
results
18
criterion
1
size
90

Class
-none-none-none-none-

Mode
numeric
numeric
character
numeric

spe.KM.cascade$results
##
##
##
##
##
##

2 groups 3 groups 4 groups 5 groups 6 groups 7 groups 8 groups


8.2149
6.4768
5.0720
4.302
3.5856
2.9524 2.48405
0.1312
0.1676
0.1245
0.115
0.1282
0.1306 0.07276
9 groups 10 groups
SSE
2.0522
1.75993
ssi
0.1267
0.07095
SSE
ssi

# el mnimo del valor SEE es el criterio para encontrar la agrupacin


# ptima de los objetos para un valor dado de k mientras que el
# mximo del ndice SSI encuentra el valor k ptimo.
# vemos que el criterio SSI se maximiza para 3 grupos.
# vemos la particin creada y la graficamos
head(spe.KM.cascade$partition)
##
##
##
##
##
##
##
##
##
##
##
##
##
##

1
2
3
4
5
6
1
2
3
4
5
6

2 groups 3 groups 4 groups 5 groups 6 groups 7 groups 8 groups


2
3
4
4
4
5
4
2
3
4
3
2
6
8
2
3
4
3
2
6
8
2
3
4
3
2
6
8
1
1
3
2
5
2
3
2
3
4
3
2
6
8
9 groups 10 groups
7
1
2
10
2
10
2
10
9
9
2
4

plot(spe.KM.cascade, sortg = TRUE)


# Evaluamos los contenidos de los cluster, en este caso para 4
# clusters. reordenamos segn los resultados del cluster
head(spe[order(spe.kmeans$cluster), ])
##
##
##
##
##
##

23
24
25
1
2

CHA TRU VAI LOC OMB BLA HOT TOX VAN CHE BAR SPI GOU BRO PER BOU
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
2
0
0
1
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
2
1
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
5
4
3
0
0
0
0
0
0
0
0
0
0
0
0
13

##
##
##
##
##
##
##
##

0
5
5
5
0
0
0
0
0
0
0
PSO ROT CAR TAN BCO PCH GRE GAR BBO ABL ANG
23
0
0
0
0
0
0
0
1
0
2
0
24
1
0
0
0
0
0
2
2
1
5
0
25
0
1
0
0
0
0
1
1
0
3
0
1
0
0
0
0
0
0
0
0
0
0
0
2
0
0
0
0
0
0
0
0
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0

# reordenamos sitios y especies con la funcin vegemite


ord.KM <- vegemite(spe, spe.kmeans$cluster)
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

222
111111 111122222223
34512346701234559678901267890
TRU ...3554351355542.321.......1.
CHA ..........12233..211.........
OMB ..........12342...11.......1.
VAI ....4554444455431343311....1.
LOC ....355554142452354352111111.
BLA ............234..5211......1.
CHE 121...121211.1325223132423443
VAN ..1....112....35.532222312233
ABL 253...............22355555555
GOU .12...11.1...122.212445534455
TOX .................4433222.1122
BRO ..1..121.....1.4.111123324354
GAR 121....1.......54122555545555
PER ......21.......4.123123411245
HOT .1................11222311121
TAN ......12......131111244435435
BAR .............12..233244524353
SPI .................143232111135
GRE .21................1123445555
ROT ..1............2....122211225
PSO .1...............111122323453
CAR .................111112312435
BOU ..................12233323455
BBO .1..................123424545
ANG ..................11122223445
BCO ....................113423345
PCH ......................1212345
sites species
29
27

head(spe[ord.KM$sites, ord.KM$species])
##
##
##
##
##
##
##

23
24
25
1
2
3

TRU CHA OMB VAI LOC BLA CHE VAN ABL GOU TOX BRO GAR PER HOT TAN
0
0
0
0
0
0
1
0
2
0
0
0
1
0
0
0
0
0
0
0
0
0
2
0
5
1
0
0
2
0
1
0
0
0
0
0
0
0
1
1
3
2
0
1
1
0
0
0
3
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
5
0
0
4
3
0
0
0
0
0
0
0
0
0
0
0
5
0
0
5
5
0
0
0
0
0
0
1
0
0
0
0
14

##
##
##
##
##
##
##

23
24
25
1
2
3

BAR SPI GRE ROT PSO CAR BOU BBO ANG BCO PCH
0
0
0
0
0
0
0
0
0
0
0
0
0
2
0
1
0
0
1
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

# los valores centrales (medios) de cada cluster, para cada variable,


# son:
head(spe.kmeans$centers[, 1:5])
##
##
##
##
##

1
2
3
4

CHA
0.00000
0.10380
0.06168
0.00000

TRU
0.000000
0.542301
0.122088
0.006691

VAI
0.00000
0.50087
0.26994
0.02506

LOC
0.00000
0.43326
0.35943
0.06987

OMB
0.000000
0.114024
0.032665
0.006691

# si usamos clustIndex (para 2 culsters)


cl <- cclust(as.matrix(spe.norm), 2, 100, verbose = TRUE, method = "kmeans")
## Error: could not find function clust
resultindexes <- clustIndex(cl, as.matrix(spe.norm), index = "all")
## Error: could not find function lustIndex
resultindexes
## Error: object resultindexesot found

ssi
criterion
10
2

10
8
6
4
2

Number of groups in each partition

Kmeans partitions comparison

10

15

20

Objects

1.2.2.

25

0.08

0.12
Values

k-medoides (PAM)

15

0.16

#
#
#
#
#
#

------# Particin alrededor de medoides (PAM) ------- ------# El


objetivo es encontrar k objetos representativos que minimicen la
suma de las disimilaridades de las observaciones respecto al objeto
representativo ms cercano. A diferencia del mtodo de k-medias,
no minimiza la suma de los cuadrados de las distancias eucldeas
dentro de los grupos (mtodo de cuadrados mnimos)

# Para determinar el nmero de clusters ptimo ------- Generamos un


# loop para calcular los anchos de silueta media desde 2 a 28
# clusters

asw <- numeric(nrow(spe))


for (k in 2:(nrow(spe) - 1)) asw[k] <- pam(spe.ch, k, diss = TRUE)$silinfo$avg.width
k.best <- which.max(asw)
cat("", "Silhouette-optimal number of clusters k =", k.best, "\n", "with an average silhouette width of"
max(asw), "\n")
##
##

Silhouette-optimal number of clusters k = 2


with an average silhouette width of 0.3841

# graficamos
plot(1:nrow(spe), asw, type = "h", main = "Choice of the number of clusters",
xlab = "k (number of clusters)", ylab = "Average silhouette width")
axis(1, k.best, paste("optimum", k.best, sep = "\n"), col = "red", font = 2,
col.axis = "red")
points(k.best, max(asw), pch = 16, col = "red", cex = 1.5)
# la opcin ptima para PAM es k=2 con asw=0.3841
# Si an as elegimos k=4 clusters para comparar con los anteriores
# mtodos
spe.ch.pam <- pam(spe.ch, k = 4, diss = TRUE)
summary(spe.ch.pam)
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

Medoids:
ID
[1,] "11" "12"
[2,] "6" "6"
[3,] "16" "17"
[4,] "25" "26"
Clustering vector:
1 2 3 4 5 6 7
1 1 1 2 2 2 1
25 26 27 28 29 30
4 4 4 4 4 4
Objective function:
build
swap
0.4426 0.4391

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
2 2 1 1 1 1 1 3 3 3 3 4 4 4 4 4

Numerical information per cluster:


size max_diss av_diss diameter separation
[1,]
9
0.8770 0.4351
1.1169
0.3429
[2,]
5
0.8815 0.4962
1.0855
0.3429
[3,]
4
0.5989 0.3679
0.8037
0.4977
[4,]
11
0.8842 0.4422
1.1276
0.4977
16

##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

Isolated clusters:
L-clusters: character(0)
L*-clusters: character(0)
Silhouette plot information:
cluster neighbor sil_width
13
1
2
0.42989
12
1
2
0.40576
2
1
2
0.38341
14
1
2
0.35676
11
1
2
0.34189
3
1
2
0.27044
1
1
2
0.24590
7
1
2
0.24136
15
1
3
0.05062
6
2
1
0.09344
10
2
1
0.06179
9
2
3
0.04917
5
2
3 -0.03817
4
2
1 -0.14709
17
3
2
0.45358
18
3
4
0.38401
16
3
2
0.23661
19
3
4
0.15365
26
4
3
0.48031
27
4
3
0.46381
28
4
3
0.45850
22
4
3
0.41331
21
4
3
0.39376
29
4
3
0.36427
30
4
3
0.36421
24
4
3
0.31070
25
4
3
0.26599
20
4
3
0.23650
23
4
3
0.21030
Average silhouette width per cluster:
[1] 0.302892 0.003827 0.306963 0.360150
Average silhouette width of total data set:
[1] 0.2736
Available components:
[1] "medoids"
"id.med"
[6] "clusinfo"
"silinfo"

"clustering" "objective"
"diss"
"call"

spe.ch.pam.g <- spe.ch.pam$clustering


spe.ch.pam$silinfo$widths
##
##
##
##
##
##

13
12
2
14
11

cluster neighbor sil_width


1
2
0.42989
1
2
0.40576
1
2
0.38341
1
2
0.35676
1
2
0.34189
17

"isolation"

##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

3
1
7
15
6
10
9
5
4
17
18
16
19
26
27
28
22
21
29
30
24
25
20
23

1
1
1
1
2
2
2
2
2
3
3
3
3
4
4
4
4
4
4
4
4
4
4
4

2
2
2
3
1
1
3
3
1
2
4
2
4
3
3
3
3
3
3
3
3
3
3
3

0.27044
0.24590
0.24136
0.05062
0.09344
0.06179
0.04917
-0.03817
-0.14709
0.45358
0.38401
0.23661
0.15365
0.48031
0.46381
0.45850
0.41331
0.39376
0.36427
0.36421
0.31070
0.26599
0.23650
0.21030

# Comparamos con las anteriores clasificaciones


table(spe.ch.pam.g, spebc.ward.g)
##
spebc.ward.g
## spe.ch.pam.g 1 2 3 4
##
1 8 1 0 0
##
2 3 2 0 0
##
3 0 4 0 0
##
4 0 0 8 3
table(spe.ch.pam.g, spe.kmeans$cluster)
##
## spe.ch.pam.g 1 2 3 4
##
1 0 9 0 0
##
2 0 3 2 0
##
3 0 0 4 0
##
4 3 0 0 8
# los resultados de PAM difieren mucho de los mtodos anteriores
# Qu solucin (PAM o k-means) tiene mejor silhouette? ----par(mfrow = c(1, 2))
k <- 4
sil <- silhouette(spe.kmeans$cluster, spe.ch)
rownames(sil) <- row.names(spe)
plot(sil, main = "Silhouette plot - k-means", cex.names = 0.8, col = 2:(k +
1))
plot(silhouette(spe.ch.pam), main = "Silhouette plot - PAM", cex.names = 0.8,
18

col = 2:(k + 1))


#
#
#
#
#

vemos como dos mtodos que tienen un mismo objetivo y clase


(no-jerrquico), producen resultados distintos el usuario debe
elegir cul es la mejor clasificacin, segn alguna otra
informacin pertinente o segn la interpretacin de los datos
ambientales, por ejemplo.

# ----------------# bonus: graficar los cluster de 4 k-means en un


# mapa con el ro Doubs ---- ----------------#
plot(spa, asp = 1, type = "n", main = "Four k-means groups", xlab = "x coordinate (km)",
ylab = "y coordinate (km)")
lines(spa, col = "light blue")
text(50, 10, "Upstream", cex = 1.2)
text(25, 115, "Downstream", cex = 1.2)
grKM <- spe.kmeans$cluster
k <- length(levels(factor(grKM)))
for (i in 1:k) {
points(spa[grKM == i, 1], spa[grKM == i, 2], pch = i + 20, cex = 3,
col = i + 1, bg = i + 1)
}
text(spa, row.names(spa), cex = 0.8, col = "white", font = 2)
legend("bottomright", paste("Cluster", 1:k), pch = (1:k) + 20, col = 2:(k +
1), pt.bg = 2:(k + 1), pt.cex = 2, bty = "n")

19

0.3
0.2
0.1
0.0

Average silhouette width

Choice of the number of clusters

optimum
2

10

15

20

25

30

k (number of clusters)

Silhouette plot kmeans

Silhouette plot PAM

4 clusters Cj
j : n1j | :ave
si
3 iCj
| 0.34

n = 29
23
24
25
2
12
3
7
11
13
14
4
1
6
10
15
17
18
16
9
5
19
22
21
27
28
29
30
26
20

13
12
2
14
11
3
1
7
15
6
10
9
5
4
17
18
16
19
26
27
28
22
21
29
30
24
25
20
23

2 : 12 | 0.37

3 : 6 | 0.08
4 : 8 | 0.59

0.0

0.2

0.4

0.6

0.8

4 clusters Cj
j : nj | aveiCj si

n = 29

1.0

1 : 9 | 0.30
2 : 5 | 0.004
3 : 4 | 0.31
4 : 11 | 0.36

0.0

Silhouette width si

0.2

0.4

0.6

0.8

Silhouette width si

Average silhouette width : 0.37

Average silhouette width : 0.27

20

1.0

29

27
28

26

30

Downstream
7
6
5
4
3
Upstream
12

50

100 150 200

25

y coordinate (km)

Four kmeans groups

50

2423
22
17 16
21
2019 18 15
14
13
12
11
10

Cluster 1
Cluster 2
Cluster 3
Cluster 4

100 150 200 250


x coordinate (km)

1.3.

PLUS: Anlisis extra para mejorar la interpretacin y validacin.

1.3.1.

Comparacin con datos ambientales.

# necesitaremos cargar los siguiente paquetes


require(pgirmess)
# comparaciones Post hoc. para instalar el paquete:
# https://rforge.net/NCStats/files/; http://www.rrforge.net/FSAdatas/
# o intentar:
# source(http://www.rforge.net/NCStats/InstallNCStats.R)
# library(FSAdata)
library(NCStats)
# -----------------# Comparacin con datos ambientales--------# Relacin entre los clusters de peces y 4 variables ambientales
# basados en los resultados del cluster k-means -----------------#
# Validacin externa:
#
#
#
#
#
#
#
#
#

1) Comparando la tipologa con datos externos (aproximacin ANOVA)


----- Hemos visto que solamente con los datos de especies, tanto
con ndices de silueta o calidad del cluster, no hemos podido
seleccionar la mejor particin de los sitios. Podemos confrontar
los resultados del cluster (respuesta) con datos externos (tal vez
generados con anlisis discriminantes para crear variables
independientes). Tambin podemos hacer el planteamiento opuesto,
considerar como factores los clusters obtenidos con los datos de
especies, para realizar un ANOVA.

attach(env)

21

# Boxplots para variables cualitativas ambientales: altitud,


# pendiente, oxgeno y amonio
par(mfrow = c(2, 2))
boxplot(sqrt(alt) ~ spe.kmeans$cluster, main = "Altitude", las = 1, ylab = "sqrt(alt)",
col = 2:5, varwidth = TRUE)
boxplot(log(pen) ~ spe.kmeans$cluster, main = "Slope", las = 1, ylab = "log(pen)",
col = 2:5, varwidth = TRUE)
boxplot(oxy ~ spe.kmeans$cluster, main = "Oxygen", las = 1, ylab = "oxy",
col = 2:5, varwidth = TRUE)
boxplot(sqrt(amm) ~ spe.kmeans$cluster, main = "Ammonium", las = 1, ylab = "sqrt(amm)",
col = 2:5, varwidth = TRUE)
# Ponemos a prueba los supuestos del ANOVA Residuos normales . Ho:
# la variable tiene distribucin normal
shapiro.test(resid(lm(sqrt(alt) ~ as.factor(spe.kmeans$cluster))))
## Shapiro-Wilk normality test with resid(lm(sqrt(alt) ~ as.factor(spe.kmeans$cluster)))
## W = 0.9624, p-value = 0.3756
shapiro.test(resid(lm(log(pen) ~ as.factor(spe.kmeans$cluster))))
## Shapiro-Wilk normality test with resid(lm(log(pen) ~ as.factor(spe.kmeans$cluster)))
## W = 0.9518, p-value = 0.204
shapiro.test(resid(lm(oxy ~ as.factor(spe.kmeans$cluster))))
## Shapiro-Wilk normality test with resid(lm(oxy ~ as.factor(spe.kmeans$cluster)))
## W = 0.9394, p-value = 0.09674
shapiro.test(resid(lm(sqrt(amm) ~ as.factor(spe.kmeans$cluster))))
## Shapiro-Wilk normality test with resid(lm(sqrt(amm) ~ as.factor(spe.kmeans$cluster)))
## W = 0.954, p-value = 0.2319
# no rechazamos normalidad
# Homogeneidad de varianza. Ho: las varianzas son iguales entre
# grupos
bartlett.test(sqrt(alt), as.factor(spe.kmeans$cluster))
## Bartlett test of homogeneity of variances with sqrt(alt) and as.factor(spe.kmeans$cluster)
## Bartlett's K-squared = 16.95, df = 3, p-value = 0.0007227
bartlett.test(log(pen), as.factor(spe.kmeans$cluster))
## Bartlett test of homogeneity of variances with log(pen) and as.factor(spe.kmeans$cluster)
## Bartlett's K-squared = 2.983, df = 3, p-value = 0.3942
bartlett.test(oxy, as.factor(spe.kmeans$cluster))
## Bartlett test of homogeneity of variances with oxy and as.factor(spe.kmeans$cluster)
## Bartlett's K-squared = 1.826, df = 3, p-value = 0.6093
bartlett.test(sqrt(amm), as.factor(spe.kmeans$cluster))
## Bartlett test of homogeneity of variances with sqrt(amm) and as.factor(spe.kmeans$cluster)
## Bartlett's K-squared = 5.72, df = 3, p-value = 0.126
22

# solo rechazamos homogeneidad de varianza para alt


# por tanto, alt lo analizamos con tcnicas no-paramtricas, y las
# dems con tcnicas paramtricas
# Realizamos el ANOVA. Ho: mu_grupo1=mu_grupo2=.....
summary(fm1 <- aov(log(pen) ~ as.factor(spe.kmeans$cluster)))
##
##
##
##
##

Df Sum Sq Mean Sq F value Pr(>F)


as.factor(spe.kmeans$cluster) 3
18.1
6.02
7.28 0.0011 **
Residuals
25
20.7
0.83
--Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

summary(fm2 <- aov(oxy ~ as.factor(spe.kmeans$cluster)))


##
##
##
##
##

Df Sum Sq Mean Sq F value Pr(>F)


as.factor(spe.kmeans$cluster) 3 103.5
34.5
26.3 6.8e-08 ***
Residuals
25
32.8
1.3
--Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

summary(fm3 <- aov(sqrt(amm) ~ as.factor(spe.kmeans$cluster)))


##
##
##
##
##

Df Sum Sq Mean Sq F value Pr(>F)


as.factor(spe.kmeans$cluster) 3 2.613
0.871
49.5 1.2e-10 ***
Residuals
25 0.439
0.018
--Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

# rechazamos igualdad de medias, para todos.


# Kruskal-Wallis test of variable alt. Ho: misma distribucin en
# todos los grupos.
(fm4 <- kruskal.test(alt ~ as.factor(spe.kmeans$cluster)))
## Kruskal-Wallis rank sum test with alt by as.factor(spe.kmeans$cluster)
## Kruskal-Wallis chi-squared = 21.53, df = 3, p-value =
## 8.186e-05
# rechazamos igualdad de medias
# realizamos comparaciones mltiples post-hoc para determinar entre
# qu cluster existen diferencias significativas. Ho:
# mu_grupo1=mu_grupo2
par(mfrow = c(2, 2))
TukeyHSD(fm1, ordered = TRUE)
##
Tukey multiple comparisons of means
##
95% family-wise confidence level
##
factor levels have been ordered
##
## Fit: aov(formula = log(pen) ~ as.factor(spe.kmeans$cluster))
##
## $`as.factor(spe.kmeans$cluster)`
23

##
##
##
##
##
##
##

4-1
3-1
2-1
3-4
2-4
2-3

diff
0.1064
0.5881
1.8129
0.4817
1.7066
1.2249

lwr
-1.58638
-1.17995
0.19896
-0.86865
0.56530
-0.02533

upr
1.799
2.356
3.427
1.832
2.848
2.475

p adj
0.9981
0.7971
0.0235
0.7613
0.0020
0.0563

plot(TukeyHSD(fm1))
TukeyHSD(fm2, ordered = TRUE)
##
##
##
##
##
##
##
##
##
##
##
##
##
##

Tukey multiple comparisons of means


95% family-wise confidence level
factor levels have been ordered
Fit: aov(formula = oxy ~ as.factor(spe.kmeans$cluster))
$`as.factor(spe.kmeans$cluster)`
diff
lwr
upr p adj
4-1 3.188 1.0532 5.322 0.0020
3-1 4.233 2.0042 6.463 0.0001
2-1 6.083 4.0484 8.118 0.0000
3-4 1.046 -0.6567 2.748 0.3500
2-4 2.896 1.4569 4.335 0.0001
2-3 1.850 0.2737 3.426 0.0171

plot(TukeyHSD(fm2))
TukeyHSD(fm3, ordered = TRUE)
##
##
##
##
##
##
##
##
##
##
##
##
##
##

Tukey multiple comparisons of means


95% family-wise confidence level
factor levels have been ordered
Fit: aov(formula = sqrt(amm) ~ as.factor(spe.kmeans$cluster))
$`as.factor(spe.kmeans$cluster)`
diff
lwr
upr p adj
3-2 0.32984 0.1475 0.5122 0.0002
4-2 0.36747 0.2010 0.5339 0.0000
1-2 1.00955 0.7742 1.2449 0.0000
4-3 0.03763 -0.1593 0.2346 0.9521
1-3 0.67971 0.4219 0.9376 0.0000
1-4 0.64208 0.3952 0.8890 0.0000

plot(TukeyHSD(fm3))
kruskalmc(alt ~ as.factor(spe.kmeans$cluster))
##
##
##
##
##
##
##

Multiple comparison test after Kruskal-Wallis


p.value: 0.05
Comparisons
obs.dif critical.dif difference
1-2 15.333
14.50
TRUE
1-3
9.833
15.88
FALSE
1-4
1.375
15.21
FALSE
24

## 2-3
## 2-4
## 3-4

5.500
16.708
11.208

11.23
10.25
12.13

FALSE
TRUE
FALSE

detach(env)
#
#
#
#
#
#
#

El procedimiento opuesto. vamos a realizar cluster con las


variables ambientales (para obtener conjuntos de tipos de hbitats)
y probar si las especies responden al tipo de habitat. Utilizaremos
anlisis de especies indicadoras, Otra alternativa sera probar la
relacin especies-hbitat directamente, ver cap. 6 de Numerical
ecology with R Of course, the reverse procedure could be applied as
well.

#
#
#
#
#

2) Tablas de continfencia de dos tipologas ------------ Si


queremos comparar la tipologa generada con los datos de especies
con aquella que obtenemos con datos ambientales podemos generar una
tabla de contingencia para cruzar ambas tipologas y probar si
existe relacin mediante la prueba de independencia Chi-cuadrado.

# Tipologa basada en datos ambientales


env2 <- env[, -1]
env.de <- vegdist(scale(env2), "euc")
set.seed(1)
env.kmeans <- kmeans(env.de, centers = 4, nstart = 100)
env.KM.4 <- env.kmeans$cluster
# Tabla de contingencia: columnas=env, filas=sp
(tab <- table(as.factor(spe.kmeans$cluster), as.factor(env.kmeans$cluster)))
##
##
##
##
##
##

1
2
3
4

1
0
7
2
0

2
0
4
4
3

3
1
0
0
5

4
2
1
0
0

# agregamos nombres
rownames(tab) <- c("sp_c1", "sp_c2", "sp_c3", "sp_c4")
colnames(tab) <- c("env_c1", "env_c2", "env_c3", "env_c4")
# Prueba de independencia Chi-cuadrado. Ho: X e Y son variables
# independientes.
(M1 <- chisq.test(tab))
## Pearson's Chi-squared test with tab
## X-squared = 30.23, df = 9, p-value = 0.0004014
# con test de permutacin
(M2 <- chisq.test(tab, simulate.p.value = TRUE))
## Pearson's Chi-squared test with simulated p-value
##
(based on 2000 replicates) with tab
## X-squared = 30.23, df = NA, p-value = 0.0004998
25

# rechazamos la independencia, por lo que existe una relacin entre


# tipologa ambiental y de especies.
# recordar: columnas=env, filas=sp
chisqPostHoc(chisq.test(t(tab))) # comparacin entre columnas (env)
##
##
##
##
##
##
##
##

Adjusted p-values used the


comparison raw.p
1 env_c1 vs. env_c2
NaN
2 env_c1 vs. env_c3 0.0018
3 env_c1 vs. env_c4
NaN
4 env_c2 vs. env_c3 0.0322
5 env_c2 vs. env_c4 0.0262
6 env_c3 vs. env_c4
NaN

chisqPostHoc(M2)
##
##
##
##
##
##
##
##
#
#
#
#

fdr method.
adj.p
NaN
0.0054
NaN
0.0322
0.0322
NaN

# comparacin entre filas (sp)

Adjusted p-values
comparison
1 sp_c1 vs. sp_c2
2 sp_c1 vs. sp_c3
3 sp_c1 vs. sp_c4
4 sp_c2 vs. sp_c3
5 sp_c2 vs. sp_c4
6 sp_c3 vs. sp_c4

used the fdr method.


raw.p adj.p
0.0127 0.0190
0.0293 0.0293
NaN
NaN
NaN
NaN
0.0050 0.0149
NaN
NaN

produce NaN cuando hay ceros en los datos Para columnas, vemos que
existen diferencias significativas entre 1-3, 1-4, 2-3. Para
filas, vemos que existen diferencias significativas entre 1-2, 1-3,
2-4.

# para que sea ms fcil la interpretacin, graficamos


library(plotrix)
barp(tab, main = "Clusters", ylab = "Value", names.arg = colnames(tab),
col = 1:4)
# agregamos leyenda
addtable2plot(-0.5, 5.5, tab, bty = "o", display.rownames = TRUE, hlines = TRUE,
title = "The table")

26

Altitude

Slope
4

30

3
2
log(pen)

sqrt(alt)

25

20

1
0
1

15

Oxygen

Ammonium

12
1.2
1.0
sqrt(amm)

0.8
0.6
0.4

6
0.2
0.0

4
1

31
41
32
42
43

42

32

41

31

21

95% familywise confidence level

21

95% familywise confidence level

43

oxy

10

27

Differences in mean levels of as.factor(spe.kmeans$cluster)

Differences in mean levels of as.factor(spe.kmeans$cluster)

1.3.2.

Ensables de especies

# -----------------# Ensambles de especies -----------------# El


# objetivo es identificar asociaciones de especies en nuestros datos.
#
#
#
#
#

1) Abundancias medias en los clusters de sitios (k-means) ------Calcularemos estadsticos simples (abundancias medias) a partir de
las tipologas obtenidas con el anlisis cluster, y miraremos qu
especies estn presentes en mayor abundancia o qu especies son
especficas de cada cluster de sitios

groups <- as.factor(spe.kmeans$cluster)


spe.means <- matrix(0, ncol(spe), length(levels(groups)))
row.names(spe.means) <- colnames(spe)
for (i in 1:ncol(spe)) {
spe.means[i, ] <- tapply(spe[, i], spe.kmeans$cluster, mean)
}
# abundancias promedio de especies para los 4 grupos
group1 <- round(sort(spe.means[, 1], decreasing = TRUE), 2)
group2 <- round(sort(spe.means[, 2], decreasing = TRUE), 2)
group3 <- round(sort(spe.means[, 3], decreasing = TRUE), 2)
group4 <- round(sort(spe.means[, 4], decreasing = TRUE), 2)
# especies con abundancias mayores que la abundancia media de
# especies del grupo
group1.domin <- which(group1 > mean(group1))
group1 #para el grupo 1
## ABL CHE GAR GOU GRE HOT VAN BRO PSO ROT BBO CHA TRU VAI
## 3.33 1.33 1.33 1.00 1.00 0.33 0.33 0.33 0.33 0.33 0.33 0.00 0.00 0.00
## LOC OMB BLA TOX BAR SPI PER BOU CAR TAN BCO PCH ANG
## 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
group1.domin

#especies con abundancias mayores que la media

## ABL CHE GAR GOU GRE


##
1
2
3
4
5
# lo mismo podemos hacer con los dems grupos
group2.domin <- which(group2 > mean(group2))
group2 #para el grupo 2
## TRU VAI LOC OMB CHE CHA BLA VAN GOU BRO TAN BAR PER GAR
## 4.00 4.00 3.58 1.00 1.00 0.92 0.75 0.58 0.50 0.42 0.33 0.25 0.25 0.08
## HOT TOX SPI BOU PSO ROT CAR BCO PCH GRE BBO ABL ANG
## 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
group2.domin

#especies con abundancias mayores que la media

## TRU VAI LOC OMB CHE CHA BLA


##
1
2
3
4
5
6
7
group3.domin <- which(group3 > mean(group3))
group3 #para el grupo 3
28

## LOC GAR VAI VAN CHE TOX GOU PER BAR SPI BLA TAN TRU BRO
## 3.67 3.17 2.83 2.83 2.50 2.33 1.83 1.83 1.67 1.67 1.50 1.50 1.33 1.33
## ABL BOU CHA HOT PSO CAR ROT ANG OMB GRE BCO BBO PCH
## 1.17 0.83 0.67 0.67 0.67 0.67 0.50 0.50 0.33 0.33 0.17 0.17 0.00
group3.domin

#especies con abundancias mayores que la media

## LOC GAR VAI VAN CHE TOX GOU PER BAR SPI BLA TAN
##
1
2
3
4
5
6
7
8
9 10 11 12
group4.domin <- which(group4 > mean(group4))
group4 #para el grupo 4
## ABL GAR GOU GRE TAN BAR BBO BOU BRO CHE BCO PSO ANG PER
## 5.00 4.88 4.38 4.12 4.00 3.75 3.62 3.50 3.25 3.12 3.12 3.00 3.00 2.75
## CAR VAN PCH SPI ROT HOT TOX LOC VAI TRU OMB BLA CHA
## 2.62 2.25 2.25 2.12 2.12 1.62 1.50 1.00 0.38 0.12 0.12 0.12 0.00
group4.domin

#especies con abundancias mayores que la media

## ABL GAR GOU GRE TAN BAR BBO BOU BRO CHE BCO PSO ANG PER CAR
##
1
2
3
4
5
6
7
8
9 10 11 12 13 14 15

#
#
#
#
#
#
#
#
#
#
#
#
#

2) Coeficiente W de Kendall para evaluar la concordancia ------*********************************************** El objetivo es


encontrar los ensambles ms globales, es decir, el menor nmero de
grupos que contendan el mayor nmero de asociaciones positivas y
significativas de especies. Legendre (2005) propuso el coeficiente
de concordancia W de Kendall para, conjuntamente con test de
permutacin, identificar ensambles de especies en datos de
abundancia (no para datos de presencia-ausencia). Primero se
utiliza un test de independencia de todas las especies si
rechazamos la hiptesis nua, miramos grupos de especies
correlacionadas y, dentro de cada grupo, evaluamos la constribucin
de cada especie al estadstico global, usando un test de
permutacin. aqu no usamos informacin de tipologa de sitios.

#
#
#
#
#
#
#

primero extraemos las especies ms abundantes del conjunto de


datos, las clasificamos con el mtodo de perticin de k-medias, y
corremos un test global (kendall.global) para conocer si todos los
grupos de especies (judges) estn asociados globalmente de manera
significativa si este es el caso, corremos test a posteriori
(kendall.post) en las especies de cada grupo para verificar si
todas las especies en un grupo son concortantes

# Extraemos la especies ms abundantes


sp.sum <- apply(spe, 2, sum)
spe.sorted <- spe[, order(sp.sum, decreasing = TRUE)]
spe.small <- spe.sorted[, 1:20]
# Transformamos los datos de especies
spe.small.hel <- decostand(spe.small, "hellinger")
29

spe.small.std <- decostand(spe.small.hel, "standardize")


spe.small.t <- t(spe.small.std)
# Realizamos una particin de k-means
spe.t.kmeans.casc <- cascadeKM(spe.small.t, inf.gr = 2, sup.gr = 8, iter = 100,
criterion = "calinski")
plot(spe.t.kmeans.casc, sortg = TRUE)
# la mejor eleccin es k=2 nos quedamos con la particin de 2 grupos
clusters <- spe.t.kmeans.casc$partition[, 1]
clusters
## LOC VAI GAR TRU ABL CHE GOU TAN VAN BAR BRO GRE PER BOU BBO PSO SPI
##
2
2
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
## ANG TOX BCO
##
1
1
1
# Realizamos un anlisis de concordancia
(spe.kendall.global <- kendall.global(spe.small.hel, clusters))
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
#
#
#
#
#
#
#

$Concordance_analysis
W
F
Prob.F
Corrected prob.F
Chi2
Prob.perm
Corrected prob.perm

Group.1
4.545e-01
1.333e+01
5.222e-43
1.044e-42
2.164e+02
1.000e-03
2.000e-03

Group.2
8.364e-01
1.022e+01
3.487e-13
3.487e-13
7.026e+01
1.000e-03
2.000e-03

$Correction.type
[1] "holm"
attr(,"class")
[1] "kendall.global"
Miramos los p-valores corregidos para el test de permutacin como
ambos grupos tienen p<0.05, decimos que todos los grupos son
significativos a nivel global i.e. de manera global, contienen
especies que son concordantes (al menos algunas especies son
concordantes) Si no fuera significativo para algunos grupos,
indicara que esos grupos deberan ser subdivididos en menores
grupos.

# Realizamos test a posteriori para identificar las especies


# significativamente concordantes en cada grupo:
(spe.kendall.post <- kendall.post(spe.small.hel, clusters, nperm = 9999))
##
##
##
##
##
##

$A_posteriori_tests_Group
$A_posteriori_tests_Group[[1]]
GAR
ABL
CHE
GOU
TAN
VAN
BAR
Spearman.mean 0.3777 0.4563 -0.09825 0.4707 0.4288 0.2341 0.4528
W.per.species 0.4143 0.4883 -0.03365 0.5019 0.4624 0.2792 0.4850
Prob
0.0018 0.0002 0.75900 0.0001 0.0001 0.0413 0.0004
30

##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

Corrected prob 0.0072


BRO
Spearman.mean 0.3088
W.per.species 0.3494
Prob
0.0094
Corrected prob 0.0282
ANG
Spearman.mean 0.5848
W.per.species 0.6093
Prob
0.0001
Corrected prob 0.0020

0.0020
GRE
0.5156
0.5441
0.0001
0.0020
TOX
0.4729
0.5040
0.0001
0.0020

0.75900 0.0020 0.0020 0.0826 0.0020


PER
BOU
BBO
PSO
SPI
0.4343 0.5823 0.5172 0.5637 0.5353
0.4675 0.6069 0.5456 0.5893 0.5626
0.0003 0.0001 0.0001 0.0001 0.0001
0.0020 0.0020 0.0020 0.0020 0.0020
BCO
0.5419
0.5689
0.0001
0.0020

$A_posteriori_tests_Group[[2]]
LOC
VAI
TRU
Spearman.mean 0.7414 0.8232 0.6976
W.per.species 0.8276 0.8822 0.7984
Prob
0.0001 0.0001 0.0001
Corrected prob 0.0020 0.0020 0.0020
$Correction.type
[1] "holm"
attr(,"class")
[1] "kendall.post"

#
#
#
#
#
#
#
#

miramos los coef. de cor. de Spearman y su p-valor corregido.


Dentro de cada grupo, las especies concordantes deben estar
positivamente asociadas con las otras Una especie con una cor.
Spearman media negativa con las dems especies de su cluster est
clasificada de manera incorrecta. lo que sugiere que debe quitarse
del grupo. Si muchas especies tienen cor neg, el grupo debe
dividirse. Especies con p-valores no sig. no estn contribuyendo a
la concordancia global del grupo, y deben quitarse.

#
#
#
#
#
#
#

--- 4) Indicadores de especies (Dufrene and Legendre)---- Dufrne


and Legendre (1997) propusieron un indicador de valores de especies
dentro de los clusters de sitios. El ndice IndVal combina la
abundancia media de especies con sus frecuencias de ocurrencias en
los grupos. Un valor alto indica gran abundancia media dentro del
grupo en comparacin con los dems grupos (especificidad) y
presencia en la mayora de sitios de ese grupo (fidelidad).

#
#
#
#

Dave Roberts, resume el concepto: The indval approach looks for


species that are both necessary and sufficient, i.e. if you find
that species you should be in that type, and if you are in that
type you should find that species.

#
#
#
#

Vamos a agrupar los sitios con datos independientes (variables


ambientales), as el indicador de especie indicar especies que
estn muy relacionadas a las condiciones ecolgicas de su grupo.
Con un test de permutacin a posteriori evaluaremos la
31

# significacin del indicador (la probabilidad de obtener por azar un


# valor del indicador como el observado)
# Dividimos los sitios en 4 grupos segn la distancia al orgen del
# ro (das). Nos preguntamos si la variable das puede subdividirse
# en grupos donde detectar especies indicadoras.
das.D1 <- dist(data.frame(das = env[, 1], row.names = rownames(env)))
set.seed(1)
dasD1.kmeans <- kmeans(das.D1, centers = 4, nstart = 100)
dasD1.kmeans$cluster
## 1 2 3 4 5 6
## 1 1 1 1 1 1
## 25 26 27 28 29 30
## 3 4 4 4 4 4

7
1

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3

# Indicador de especies para esta tipologa de sitios


(iva <- indval(spe, dasD1.kmeans$cluster))
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

$relfrq
CHA
TRU
VAI
LOC
OMB
BLA
HOT
TOX
VAN
CHE
BAR
SPI
GOU
BRO
PER
BOU
PSO
ROT
CAR
TAN
BCO
PCH
GRE
GAR
BBO
ABL
ANG

1
0.000
0.875
0.875
0.875
0.000
0.000
0.000
0.000
0.375
0.625
0.000
0.000
0.375
0.500
0.375
0.000
0.000
0.125
0.000
0.500
0.000
0.000
0.000
0.375
0.000
0.000
0.000

2
0.8
0.9
1.0
1.0
0.7
0.7
0.3
0.4
0.6
0.9
0.6
0.4
0.7
0.5
0.4
0.3
0.4
0.1
0.4
0.5
0.1
0.0
0.2
0.4
0.1
0.3
0.3

3
0.0000
0.0000
0.3333
0.5000
0.0000
0.0000
0.6667
0.5000
0.6667
1.0000
0.5000
0.5000
0.8333
0.6667
0.5000
0.5000
0.6667
0.6667
0.5000
0.5000
0.5000
0.3333
0.8333
1.0000
0.6667
1.0000
0.5000

4
0.0
0.2
0.2
0.8
0.2
0.2
1.0
0.8
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0
1.0

$relabu

1
2
3
4
CHA 0.00000 1.00000 0.00000 0.00000
TRU 0.52124 0.44788 0.00000 0.03089
VAI 0.42299 0.50759 0.04338 0.02603
32

##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

LOC
OMB
BLA
HOT
TOX
VAN
CHE
BAR
SPI
GOU
BRO
PER
BOU
PSO
ROT
CAR
TAN
BCO
PCH
GRE
GAR
BBO
ABL
ANG

0.40385
0.00000
0.00000
0.00000
0.00000
0.14325
0.16484
0.00000
0.00000
0.05660
0.15152
0.15419
0.00000
0.00000
0.06726
0.00000
0.11706
0.00000
0.00000
0.00000
0.12235
0.00000
0.00000
0.00000

$indval
CHA
TRU
VAI
LOC
OMB
BLA
HOT
TOX
VAN
CHE
BAR
SPI
GOU
BRO
PER
BOU
PSO
ROT
CAR
TAN
BCO
PCH
GRE
GAR
BBO
ABL
ANG

1
0.000000
0.456081
0.370119
0.353365
0.000000
0.000000
0.000000
0.000000
0.053718
0.103022
0.000000
0.000000
0.021226
0.075758
0.057819
0.000000
0.000000
0.008408
0.000000
0.058528
0.000000
0.000000
0.000000
0.045881
0.000000
0.000000
0.000000

0.42692
0.87500
0.90000
0.13636
0.38889
0.27831
0.19181
0.18932
0.23810
0.14717
0.07576
0.12335
0.08621
0.07792
0.02691
0.09091
0.08027
0.02069
0.00000
0.02857
0.09788
0.01734
0.07095
0.06122

0.07692
0.00000
0.00000
0.45455
0.27778
0.21828
0.25974
0.31553
0.23810
0.32075
0.22727
0.26432
0.25862
0.25974
0.31390
0.22727
0.26756
0.27586
0.14286
0.28571
0.30995
0.28902
0.42230
0.20408

2
0.800000
0.403089
0.507592
0.426923
0.612500
0.630000
0.040909
0.155556
0.166985
0.172627
0.113592
0.095238
0.103019
0.037879
0.049339
0.025862
0.031169
0.002691
0.036364
0.040134
0.002069
0.000000
0.005714
0.039152
0.001734
0.021284
0.018367

0.09231
0.12500
0.10000
0.40909
0.33333
0.36016
0.38362
0.49515
0.52381
0.47547
0.54545
0.45815
0.65517
0.66234
0.59193
0.68182
0.53512
0.70345
0.85714
0.68571
0.46982
0.69364
0.50676
0.73469

3
0.00000
0.00000
0.01446
0.03846
0.00000
0.00000
0.30303
0.13889
0.14552
0.25974
0.15777
0.11905
0.26730
0.15152
0.13216
0.12931
0.17316
0.20927
0.11364
0.13378
0.13793
0.04762
0.23810
0.30995
0.19268
0.42230
0.10204

4
0.000000
0.006178
0.005206
0.073846
0.025000
0.020000
0.409091
0.266667
0.360164
0.383616
0.495146
0.523810
0.475472
0.545455
0.458150
0.655172
0.662338
0.591928
0.681818
0.535117
0.703448
0.857143
0.685714
0.469821
0.693642
0.506757
0.734694
33

##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

$maxcls
CHA TRU VAI LOC OMB BLA HOT TOX VAN CHE BAR SPI GOU BRO PER BOU PSO
2
1
2
2
2
2
4
4
4
4
4
4
4
4
4
4
4
ROT CAR TAN BCO PCH GRE GAR BBO ABL ANG
4
4
4
4
4
4
4
4
4
4
$indcls
CHA
TRU
VAI
LOC
OMB
BLA
HOT
TOX
VAN
CHE
0.8000 0.4561 0.5076 0.4269 0.6125 0.6300 0.4091 0.2667 0.3602 0.3836
BAR
SPI
GOU
BRO
PER
BOU
PSO
ROT
CAR
TAN
0.4951 0.5238 0.4755 0.5455 0.4581 0.6552 0.6623 0.5919 0.6818 0.5351
BCO
PCH
GRE
GAR
BBO
ABL
ANG
0.7034 0.8571 0.6857 0.4698 0.6936 0.5068 0.7347
$pval
CHA
TRU
VAI
LOC
OMB
BLA
HOT
TOX
VAN
CHE
BAR
0.001 0.021 0.001 0.011 0.007 0.005 0.052 0.283 0.128 0.029 0.009
SPI
GOU
BRO
PER
BOU
PSO
ROT
CAR
TAN
BCO
PCH
0.013 0.009 0.006 0.031 0.001 0.001 0.007 0.001 0.001 0.003 0.001
GRE
GAR
BBO
ABL
ANG
0.002 0.015 0.001 0.009 0.001
attr(,"class")
[1] "indval"

# relfrq=frecuencia relativa de especies en cada grupo


# relabu=frecuencia relativa de abundancia de especies en los groupss
# idval=valor indicador de cada especie
# Tabla de especies indicadoras significativas
gr <- iva$maxcls[iva$pval <= 0.05]
iv <- iva$indcls[iva$pval <= 0.05]
pv <- iva$pval[iva$pval <= 0.05]
fr <- apply(spe > 0, 2, sum)[iva$pval <= 0.05]
fidg <- data.frame(group = gr, indval = iv, pvalue = pv, freq = fr)
fidg <- fidg[order(fidg$group, -fidg$indval), ]
fidg
##
##
##
##
##
##
##
##
##
##
##
##
##
##
##

TRU
CHA
BLA
OMB
VAI
LOC
PCH
ANG
BCO
BBO
GRE
CAR
PSO
BOU

group
1
2
2
2
2
2
4
4
4
4
4
4
4
4

indval pvalue freq


0.4561 0.021
17
0.8000 0.001
8
0.6300 0.005
8
0.6125 0.007
8
0.5076 0.001
20
0.4269 0.011
24
0.8571 0.001
7
0.7347 0.001
11
0.7034 0.003
9
0.6936 0.001
10
0.6857 0.002
12
0.6818 0.001
12
0.6623 0.001
13
0.6552 0.001
11
34

##
##
##
##
##
##
##
##
##
##
#
#
#
#

ROT
BRO
TAN
SPI
ABL
BAR
GOU
GAR
PER
CHE

4
4
4
4
4
4
4
4
4
4

0.5919
0.5455
0.5351
0.5238
0.5068
0.4951
0.4755
0.4698
0.4581
0.3836

0.007
0.006
0.001
0.013
0.009
0.009
0.009
0.015
0.031
0.029

11
18
17
12
14
14
20
18
15
25

para saber a qu especies refieren cada abreviacin, podemos:


data(doubs) y preguntar sobre estos datos ?doubs Vemos que el
cluster 2 tiene como especie indicadora el TRU (Salmo trutta
fario), etc.

# Podemos exportar los resultados en un archiv csv


write.csv(fidg, "IndVal-das.csv")

35

calinski
criterion

8
7
6
2

6
5
4
3
2

Number of groups in each partition

Kmeans partitions comparison

10

15

Objects

20

8.0

9.0 10.0
Values

36

You might also like