@@ -167,6 +167,34 @@ print.phyloLayout <- function(obj) {
167
167
}
168
168
169
169
170
+ .get.root <- function (edges ) {
171
+ idx <- which(! is.element(edges $ parent , edges $ child ))
172
+ root <- unique(edges $ parent [idx ])
173
+ if (length(root ) == 0 ) {
174
+ stop(" Failed to find root in .get.root" )
175
+ }
176
+ if (length(root ) > 1 ) {
177
+ stop(" Found multiple roots in .get.root" )
178
+ }
179
+ root
180
+ }
181
+
182
+ .reorder.nodes <- function (edges , node , order , result = c()) {
183
+ if (order == ' preorder' ) {
184
+ result <- c(result , node ) # parent before children
185
+ }
186
+
187
+ children <- edges $ child [edges $ parent == node ]
188
+ for (child in children ) {
189
+ result <- .reorder.nodes(edges , child , order , result )
190
+ }
191
+ if (order == ' postorder' ) {
192
+ result <- c(result , node ) # children before parent
193
+ }
194
+ return (result )
195
+ }
196
+
197
+
170
198
171
199
# ' .layout.rect
172
200
# '
@@ -183,18 +211,13 @@ print.phyloLayout <- function(obj) {
183
211
pd $ nodes $ y [tips ] <- 1 : Ntip(phy )
184
212
185
213
# assign vertical positions to internal nodes
186
- max.n.tips <- max(pd $ nodes $ n.tips )
187
- for (i in 1 : max.n.tips ) {
188
- internals <- which(pd $ nodes $ n.tips == i )
189
- for (j in internals ) {
190
- children <- pd $ edges $ child [pd $ edges $ parent == j ]
191
- pd $ nodes $ y [j ] <- mean(pd $ nodes $ y [children ])
214
+ root <- .get.root(pd $ edges )
215
+ for (i in .reorder.nodes(pd $ edges , root , order = ' postorder' )) {
216
+ if (i > Ntip(phy )) {
217
+ children <- pd $ edges $ child [pd $ edges $ parent == i ]
218
+ pd $ nodes $ y [i ] <- mean(pd $ nodes $ y [children ])
192
219
}
193
220
}
194
-
195
- root <- Ntip(phy )+ 1
196
- children <- pd $ edges $ child [pd $ edges $ parent == root ]
197
- pd $ nodes $ y [root ] <- mean(pd $ nodes $ y [children ])
198
221
199
222
# map node coordinates to edges
200
223
pd $ edges $ x0 <- pd $ nodes $ x [pd $ edges $ parent ]
@@ -234,18 +257,13 @@ print.phyloLayout <- function(obj) {
234
257
pd $ nodes $ angle [tips ] <- (1 : Ntip(phy )) / Ntip(phy ) * 2 * pi
235
258
236
259
# assign angles to internal nodes
237
- max.n.tips <- max(pd $ nodes $ n.tips )
238
- for (i in 1 : max.n.tips ) {
239
- internals <- which(pd $ nodes $ n.tips == i )
240
- for (j in internals ) {
241
- children <- pd $ edges $ child [pd $ edges $ parent == j ]
242
- pd $ nodes $ angle [j ] <- mean(pd $ nodes $ angle [children ])
260
+ root <- .get.root(pd $ edges )
261
+ for (i in .reorder.nodes(pd $ edges , root , order = ' postorder' )) {
262
+ if (i > Ntip(phy )) {
263
+ children <- pd $ edges $ child [pd $ edges $ parent == i ]
264
+ pd $ nodes $ angle [i ] <- mean(pd $ nodes $ angle [children ])
243
265
}
244
266
}
245
-
246
- root <- Ntip(phy )+ 1
247
- children <- pd $ edges $ child [pd $ edges $ parent == root ]
248
- pd $ nodes $ angle [root ] <- mean(pd $ nodes $ angle [children ])
249
267
250
268
# calculate x,y from polar coordinates
251
269
pd $ nodes $ x <- pd $ nodes $ r * cos(pd $ nodes $ angle )
0 commit comments