@@ -26,9 +26,9 @@ cor_sort <- function(x, distance = "correlation", hclust_method = "complete", ..
26
26
27
27
# ' @export
28
28
cor_sort.easycorrelation <- function (x , distance = " correlation" , hclust_method = " complete" , ... ) {
29
- col_order <- .cor_sort_order (as.matrix(x ), distance = distance , hclust_method = hclust_method , ... )
30
- x $ Parameter1 <- factor (x $ Parameter1 , levels = col_order )
31
- x $ Parameter2 <- factor (x $ Parameter2 , levels = col_order )
29
+ m <- cor_sort (as.matrix(x ), distance = distance , hclust_method = hclust_method , ... )
30
+ x $ Parameter1 <- factor (x $ Parameter1 , levels = rownames( m ) )
31
+ x $ Parameter2 <- factor (x $ Parameter2 , levels = colnames( m ) )
32
32
reordered <- x [order(x $ Parameter1 , x $ Parameter2 ), ]
33
33
34
34
# Restore class and attributes
@@ -38,6 +38,8 @@ cor_sort.easycorrelation <- function(x, distance = "correlation", hclust_method
38
38
)
39
39
40
40
# Make sure Parameter columns are character
41
+ # Was added to fix a test, but makes the function not work
42
+ # (See https://github.com/easystats/correlation/issues/259)
41
43
# reordered$Parameter1 <- as.character(reordered$Parameter1)
42
44
# reordered$Parameter2 <- as.character(reordered$Parameter2)
43
45
@@ -55,18 +57,32 @@ cor_sort.easycormatrix <- function(x, distance = "correlation", hclust_method =
55
57
m <- x
56
58
row.names(m ) <- x $ Parameter
57
59
m <- as.matrix(m [names(m )[names(m ) != " Parameter" ]])
58
- col_order <- .cor_sort_order(m , distance = distance , hclust_method = hclust_method , ... )
60
+
61
+ # If non-redundant matrix, fail (## TODO: fix that)
62
+ if (anyNA(m )) {
63
+ insight :: format_error(" Non-redundant matrices are not supported yet. Try again by setting summary(..., redundant = TRUE)" )
64
+ }
65
+
66
+ # Get sorted matrix
67
+ m <- cor_sort(m , distance = distance , hclust_method = hclust_method , ... )
59
68
60
69
# Reorder
61
- x $ Parameter <- factor (x $ Parameter , levels = col_order )
62
- reordered <- x [order(x $ Parameter ), c(" Parameter" , col_order )]
70
+ x $ Parameter <- factor (x $ Parameter , levels = row.names( m ) )
71
+ reordered <- x [order(x $ Parameter ), c(" Parameter" , colnames( m ) )]
63
72
64
73
# Restore class and attributes
65
74
attributes(reordered ) <- utils :: modifyList(
66
75
attributes(x )[! names(attributes(x )) %in% c(" names" , " row.names" )],
67
76
attributes(reordered )
68
77
)
69
78
79
+ # Reorder attributes (p-values) etc.
80
+ for (id in c(" p" , " CI" , " CI_low" , " CI_high" , " BF" , " Method" , " n_Obs" , " df_error" , " t" )) {
81
+ if (id %in% names(attributes(reordered ))) {
82
+ attributes(reordered )[[id ]] <- attributes(reordered )[[id ]][order(x $ Parameter ), names(reordered )]
83
+ }
84
+ }
85
+
70
86
# make sure Parameter columns are character
71
87
reordered $ Parameter <- as.character(reordered $ Parameter )
72
88
@@ -76,8 +92,13 @@ cor_sort.easycormatrix <- function(x, distance = "correlation", hclust_method =
76
92
77
93
# ' @export
78
94
cor_sort.matrix <- function (x , distance = " correlation" , hclust_method = " complete" , ... ) {
79
- col_order <- .cor_sort_order(x , distance = distance , hclust_method = hclust_method , ... )
80
- reordered <- x [col_order , col_order ]
95
+ if (isSquare(x ) && all(colnames(x ) %in% rownames(x ))) {
96
+ i <- .cor_sort_square(x , distance = distance , hclust_method = hclust_method , ... )
97
+ } else {
98
+ i <- .cor_sort_nonsquare(x , distance = " euclidean" , ... )
99
+ }
100
+
101
+ reordered <- x [i $ row_order , i $ col_order ]
81
102
82
103
# Restore class and attributes
83
104
attributes(reordered ) <- utils :: modifyList(
@@ -91,7 +112,7 @@ cor_sort.matrix <- function(x, distance = "correlation", hclust_method = "comple
91
112
# Utils -------------------------------------------------------------------
92
113
93
114
94
- .cor_sort_order <- function (m , distance = " correlation" , hclust_method = " complete" , ... ) {
115
+ .cor_sort_square <- function (m , distance = " correlation" , hclust_method = " complete" , ... ) {
95
116
if (distance == " correlation" ) {
96
117
d <- stats :: as.dist((1 - m ) / 2 ) # r = -1 -> d = 1; r = 1 -> d = 0
97
118
} else if (distance == " raw" ) {
@@ -101,5 +122,54 @@ cor_sort.matrix <- function(x, distance = "correlation", hclust_method = "comple
101
122
}
102
123
103
124
hc <- stats :: hclust(d , method = hclust_method )
104
- row.names(m )[hc $ order ]
125
+ row_order <- row.names(m )[hc $ order ]
126
+ list (row_order = row_order , col_order = row_order )
127
+ }
128
+
129
+
130
+ .cor_sort_nonsquare <- function (m , distance = " euclidean" , ... ) {
131
+ # Step 1: Perform clustering on rows and columns independently
132
+ row_dist <- stats :: dist(m , method = distance ) # Distance between rows
133
+ col_dist <- stats :: dist(t(m ), method = distance ) # Distance between columns
134
+
135
+ row_hclust <- stats :: hclust(row_dist , method = " average" )
136
+ col_hclust <- stats :: hclust(col_dist , method = " average" )
137
+
138
+ # Obtain clustering orders
139
+ row_order <- row_hclust $ order
140
+ col_order <- col_hclust $ order
141
+
142
+ # Reorder matrix based on clustering
143
+ clustered_matrix <- m [row_order , col_order ]
144
+
145
+ # Step 2: Refine alignment to emphasize strong correlations along the diagonal
146
+ n_rows <- nrow(clustered_matrix )
147
+ n_cols <- ncol(clustered_matrix )
148
+
149
+ used_rows <- logical (n_rows )
150
+ refined_row_order <- integer(0 )
151
+
152
+ for (col in seq_len(n_cols )) {
153
+ max_value <- - Inf
154
+ best_row <- NA
155
+
156
+ for (row in seq_len(n_rows )[! used_rows ]) {
157
+ if (abs(clustered_matrix [row , col ]) > max_value ) {
158
+ max_value <- abs(clustered_matrix [row , col ])
159
+ best_row <- row
160
+ }
161
+ }
162
+
163
+ if (! is.na(best_row )) {
164
+ refined_row_order <- c(refined_row_order , best_row )
165
+ used_rows [best_row ] <- TRUE
166
+ }
167
+ }
168
+
169
+ # Append any unused rows at the end
170
+ refined_row_order <- c(refined_row_order , which(! used_rows ))
171
+
172
+ # Apply
173
+ m <- clustered_matrix [refined_row_order , ]
174
+ list (row_order = rownames(m ), col_order = colnames(m ))
105
175
}
0 commit comments