forked from biometry/bipartite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsortweb2.R
94 lines (81 loc) · 3.73 KB
/
sortweb2.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
#-- sortweb2: adjustments to matrix, outsorced from plotweb and adapted -------
# by Jochen Fründ, May2021 (but largely copied code from Bernd Gruber's plotweb)
# for development only
# web <- testweb
sortweb2 <- function(web, sort.order="dec", empty=TRUE, sequence=NULL){
if (empty) {web <- empty(web)}
web <- as.matrix(web) # to convert data.frames into matrix: needed for cumsum
# give rownames & colnames if missing
colnames(web) <- colnames(web, do.NULL = FALSE)
rownames(web) <- rownames(web, do.NULL = FALSE)
# choose sort.order (method in plotwebr)
methods <- c("normal", "cca", "sequence", "decreasing", "increasing")
method.matched <- methods[pmatch(sort.order, methods)]
if (is.na(method.matched)) stop("Choose one of the available sorting-methods (sort.order in sortweb)!\n")
if (method.matched=="cca"){
# all cases where cca wouldn't work now combined in one place
if (NROW(web) == 1 | NCOL(web) ==1 | length(unique(as.vector(web))) == 1) {
method.matched <- "normal"
}
if (any(rowSums(web)==0, colSums(web)==0)) {
method.matched <- "normal"
warning("cannot use cca with 0-rows/cols, using sort.order='normal' instead")
}
}
# simplest sorting as start; for sort.order="normal", no other sorting will be applied
row.seq <- 1:nrow(web)
col.seq <- 1:ncol(web)
# option "cca" = the web is re-arranged by ordination (& separating compartments)
if (method.matched=="cca"){
# Problem: cca sometimes doesn't get the compartments right!
# Solution: Function "compart" returns a matrix with links assigned to compartments
# So, we need to extract the compartments there and put them in sequence, sort by cca within
co <- compart(web)
# do the arrangement for each compartment separately
row.seq <- NULL
col.seq <- NULL
for (m in 1:co$n.compart){
comp.member <- which(abs(co$cweb)==m, arr.ind=TRUE)
rs <- unique(comp.member[,1])
cs <- unique(comp.member[,2])
if (length(rs) < 3 | length(cs) < 3){
row.seq <- c(row.seq, rs)
col.seq <- c(col.seq, cs)
} else { # works fine for webs with only one compartment
ca <- cca(web[rs, cs])
row.seq <- c(row.seq, rs[order(summary(ca)$sites[,1], decreasing=TRUE)])
col.seq <- c(col.seq, cs[order(summary(ca)$species[,1], decreasing=TRUE)])
}
}
} # end of cca method
if (method.matched=="increasing"){
web <- web[order(rowSums(web),decreasing=FALSE), order(colSums(web),decreasing=FALSE)]
}
if (method.matched=="decreasing"){
web <- web[order(rowSums(web),decreasing=TRUE), order(colSums(web),decreasing=TRUE)]
}
if (!is.null(sequence) & method.matched!="sequence") {
# warning("giving a sorting sequence overrides other sorting options")
}
if (method.matched=="sequence"){
if (is.null(sequence) | !is.list(sequence)) stop("Please give sequences as properly formatted list (see ?sortweb).")
if (length(sequence)==2){
if (is.null(names(sequence))){
# for compatibility with old sortweb and for convenience, accept other or missing names
names(sequence) <- c("seq.low","seq.high")
}
if (all(names(sequence)==c("seq.lower","seq.higher"))){
# for compatibility with old sortweb and for convenience, accept other or missing names
names(sequence) <- c("seq.low","seq.high")
}
}
row.seq <- sequence$seq.low[sequence$seq.low %in% rownames(web)]
col.seq <- sequence$seq.high[sequence$seq.high %in% colnames(web)]
}
web <- web[row.seq, col.seq, drop=FALSE] # now called once for all methods (sort.orders)
return(web)
}
# Examples:
# sortweb2(testweb)
# sortweb2(testweb, sequence=list(rownames(testweb)[3:2], colnames(testweb)[1:5]))
# sortweb2(testweb, empty=FALSE)