Browse code

fixed drop.tip issues

guangchuang yu authored on 11/11/2016 05:33:47
Showing 15 changed files

... ...
@@ -7,8 +7,7 @@ Authors@R: c(
7 7
 	   person("Tommy Tsan-Yuk", "Lam", email = "tylam.tommy@gmail.com", rol = c("aut", "ths")),
8 8
 	   person("Justin", "Silverman", email = "jsilve24@gmail.com", rol = "ctb", comment = "geom_balance"),
9 9
 	   person("Casey", "Dunn", email = "casey_dunn@brown.edu", rol = "ctb",
10
-	          comment = c("propose using txtConnection so that parser functions can use tree strings as input",
11
-		  "modified nhx parsing to retain tip node numbers"))
10
+	          comment = c("NHX"))
12 11
 	   )
13 12
 Maintainer: Guangchuang Yu <guangchuangyu@gmail.com>
14 13
 Description: 'ggtree' extends the 'ggplot2' plotting system which implemented the grammar of graphics.
... ...
@@ -157,10 +157,7 @@ exportMethods(plot)
157 157
 exportMethods(reroot)
158 158
 exportMethods(scale_color)
159 159
 exportMethods(show)
160
-importFrom(ape,Nnode)
161
-importFrom(ape,Ntip)
162 160
 importFrom(ape,di2multi)
163
-importFrom(ape,drop.tip)
164 161
 importFrom(ape,extract.clade)
165 162
 importFrom(ape,getMRCA)
166 163
 importFrom(ape,is.binary.tree)
... ...
@@ -1,5 +1,6 @@
1 1
 CHANGES IN VERSION 1.7.3
2 2
 ------------------------
3
+ o drop.tip method for NHX object <2016-11-11, Fri>
3 4
  o update startup message <2016-11-09, Wed>
4 5
  o reverse timescale x-axis <2016-11-07, Mon>
5 6
    + https://github.com/GuangchuangYu/ggtree/issues/87
... ...
@@ -164,3 +164,19 @@ setGeneric("scale_color", function(object, by, ...) standardGeneric("scale_color
164 164
 ##' @return figure
165 165
 ##' @export
166 166
 setGeneric("gzoom", function(object, focus, subtree=FALSE, widths=c(.3, .7), ...) standardGeneric("gzoom"))
167
+
168
+
169
+##' @docType methods
170
+##' @name drop.tip
171
+##' @rdname drop.tip-methods
172
+##' @title drop.tip method
173
+##' @param object An nhx or phylo object
174
+##' @param tip a vector of mode numeric or character specifying the tips to delete
175
+##' @param ... additional parameters
176
+##' @return updated object
177
+##' @export
178
+setGeneric (
179
+	name = "drop.tip",
180
+	def = function( object, tip, ... )
181
+		{ standardGeneric("drop.tip") }
182
+)
... ...
@@ -28,12 +28,11 @@ rtree <- ape::rtree
28 28
 
29 29
 ##' merge phylo and output of boot.phylo to 'apeBootstrap' object
30 30
 ##'
31
-##' 
31
+##'
32 32
 ##' @title apeBoot
33 33
 ##' @param phylo phylo
34 34
 ##' @param boot bootstrap values
35 35
 ##' @return an instance of 'apeBootstrap'
36
-##' @importFrom ape Nnode
37 36
 ##' @export
38 37
 ##' @author Guangchuang Yu
39 38
 apeBoot <- function(phylo, boot) {
... ...
@@ -53,7 +52,7 @@ setMethod("show", signature(object = "apeBootstrap"),
53 52
           function(object) {
54 53
               cat("'apeBoot' S4 object that stored bootstrap value generated by 'ape::boot.phylo'", ".\n\n")
55 54
               cat("...@ tree: ")
56
-              print.phylo(get.tree(object))                  
55
+              print.phylo(get.tree(object))
57 56
           })
58 57
 
59 58
 
... ...
@@ -1,24 +1,23 @@
1 1
 
2 2
 ##' collapse binary tree to polytomy by applying 'fun' to 'feature'
3 3
 ##'
4
-##' 
4
+##'
5 5
 ##' @title as.polytomy
6 6
 ##' @param tree tree object
7 7
 ##' @param feature selected feature
8 8
 ##' @param fun function to select nodes to collapse
9 9
 ##' @return polytomy tree
10 10
 ##' @author Guangchuang
11
-##' @importFrom ape Ntip
12 11
 ##' @importFrom ape di2multi
13 12
 ##' @export
14 13
 as.polytomy <- function(tree, feature, fun) {
15 14
     if (!is(tree, 'phylo')) {
16 15
         stop("currently only 'phylo' object is supported...")
17 16
     }
18
-    
17
+
19 18
     df <- fortify(tree)
20 19
     phylo <- get.tree(tree)
21
-    
20
+
22 21
     if (feature == 'node.label') {
23 22
         feat <- df[!df$isTip, 'label']
24 23
     } else if (feature == 'tip.label') {
... ...
@@ -26,7 +25,7 @@ as.polytomy <- function(tree, feature, fun) {
26 25
     } else {
27 26
         feat <- df[, feature]
28 27
     }
29
-    
28
+
30 29
     idx <- which(fun(feat))
31 30
     if (feature == 'node.label') {
32 31
         nodes <- Ntip(phylo) + df$node[idx]
... ...
@@ -36,7 +35,7 @@ as.polytomy <- function(tree, feature, fun) {
36 35
     edge_idx <- match(nodes, phylo$edge[,2])
37 36
     phylo$edge.length[edge_idx] <- 0
38 37
     poly_tree <- di2multi(phylo)
39
-    ## 
38
+    ##
40 39
     ## map stats to poly_tree and update tree object
41 40
     ##
42 41
     return(poly_tree)
... ...
@@ -1,12 +1,11 @@
1 1
 ##' merge two tree object
2 2
 ##'
3
-##' 
3
+##'
4 4
 ##' @title merge_tree
5 5
 ##' @param obj1 tree object 1
6 6
 ##' @param obj2 tree object 2
7 7
 ##' @return tree object
8 8
 ##' @importFrom magrittr %<>%
9
-##' @importFrom ape Ntip
10 9
 ##' @export
11 10
 ##' @author Guangchuang Yu
12 11
 merge_tree <- function(obj1, obj2) {
... ...
@@ -14,11 +13,11 @@ merge_tree <- function(obj1, obj2) {
14 13
     ## INFO:
15 14
     ## ape::all.equal.phylo can be used to test equal phylo topology.
16 15
     ##
17
-    
16
+
18 17
     if (has.slot(obj1, "extraInfo") == FALSE) {
19 18
         stop("input tree object is not supported...")
20 19
     }
21
-    
20
+
22 21
     if ((is.tree(obj1) & is.tree(obj2)) == FALSE) {
23 22
         stop("input should be tree objects...")
24 23
     }
... ...
@@ -33,7 +32,7 @@ merge_tree <- function(obj1, obj2) {
33 32
     if (Ntip(tr1) != Ntip(tr2)) {
34 33
         stop("number of tips not equals...")
35 34
     }
36
-    
35
+
37 36
     if (all(tr1$tip.label %in% tr2$tip.label) == FALSE) {
38 37
         stop("tip names not match...")
39 38
     }
... ...
@@ -56,7 +55,7 @@ merge_tree <- function(obj1, obj2) {
56 55
     node_map$from %<>% c(root.2)
57 56
     node_map$to %<>% c(root)
58 57
 
59
-    
58
+
60 59
     currentNode <- 1:Ntip(tr1)
61 60
     while(length(currentNode)) {
62 61
         p1 <- sapply(currentNode, getParent, tr=tr1)
... ...
@@ -75,7 +74,7 @@ merge_tree <- function(obj1, obj2) {
75 74
             tr2$edge[jj,1] <- p1[notNA]
76 75
         }
77 76
 
78
-        
77
+
79 78
         ii <- match(p2, tr2$edge[,2])
80 79
         if (length(ii)) {
81 80
             notNA <- which(!is.na(ii))
... ...
@@ -87,7 +86,7 @@ merge_tree <- function(obj1, obj2) {
87 86
 
88 87
         node_map$from %<>% c(p2)
89 88
         node_map$to %<>% c(p1)
90
-        
89
+
91 90
         ## parent of root will return 0, which is in-valid node ID
92 91
         currentNode <- unique(p1[p1 != 0])
93 92
     }
... ...
@@ -95,7 +94,7 @@ merge_tree <- function(obj1, obj2) {
95 94
     if ( any(tr2$edge != tr2$edge) ) {
96 95
         stop("trees are not identical...")
97 96
     }
98
-    
97
+
99 98
     node_map.df <- do.call("cbind", node_map)
100 99
     node_map.df <- unique(node_map.df)
101 100
     node_map.df <- node_map.df[node_map.df[,1] != 0,]
... ...
@@ -118,6 +117,6 @@ merge_tree <- function(obj1, obj2) {
118 117
         info <- merge(extraInfo, info2, by.x =c("node", "parent"), by.y = c("node", "parent"))
119 118
         obj1@extraInfo <- info
120 119
     }
121
-    
120
+
122 121
     return(obj1)
123 122
 }
... ...
@@ -1,57 +1,69 @@
1
-#' Drop a tip
2
-#' 
3
-#' @param object An nhx object
4
-#' @return An nhx object
5
-#' @export
6
-setGeneric (
7
-	name = "drop.tip", 
8
-	def = function( object, ... ) 
9
-		{ standardGeneric("drop.tip") }
10
-)
11
-
12
-
13 1
 ##' drop.tip method
14 2
 ##'
15 3
 ##'
16
-##' @docType methods
17
-##' @name drop.tip
18 4
 ##' @rdname drop.tip-methods
19 5
 ##' @aliases drop.tip,nhx
20 6
 ##' @exportMethod drop.tip
21
-##' @author Casey Dunn \url{http://dunnlab.org}
22
-##' @usage drop.tip(object, tip...)
7
+##' @author Casey Dunn \url{http://dunnlab.org}  and Guangchuang Yu \url{https://guangchuangyu.github.io}
8
+##' @usage drop.tip(object, tip, ...)
23 9
 setMethod("drop.tip", signature(object="nhx"),
24
-		function(object, tip) {
10
+          function(object, tip, ...) {
11
+
12
+              ## label the internal tree nodes by their number
13
+              no_node_label <- FALSE
14
+              if (is.null(object@phylo$node.label)) {
15
+                  object@phylo$node.label <- Ntip(object) + (1:Nnode(object))
16
+                  no_node_label <- TRUE
17
+              }
18
+
19
+              ## Prepare the nhx object for subsampling
20
+              object@nhx_tags$node <- as.numeric(object@nhx_tags$node)
21
+              object@nhx_tags <- object@nhx_tags[order(object@nhx_tags$node),]
22
+
23
+              ## add a colmn that has labels for both tips and internal nodes
24
+              object@nhx_tags$node.label <- c(object@phylo$tip.label, as.character(object@phylo$node.label))
25 25
 
26
-			# label the internal tree nodes by their number
27
-			object@phylo$node.label = NULL
28
-			object@phylo$node.label = (length(object@phylo$tip.label)+1):max(object@phylo$edge)
26
+              ## Will need to take different approaches for subsampling tips
27
+              ## and internal nodes, add a column to make it easy to tell them apart
28
+              object@nhx_tags$is_tip <- object@nhx_tags$node <= Ntip(object)
29 29
 
30
-			# Prepare the nhx object for subsampling
31
-			object@nhx_tags$node = as.numeric(object@nhx_tags$node)
32
-			object@nhx_tags = object@nhx_tags[order(object@nhx_tags$node),]
30
+              ## Remove tips
31
+              object@phylo = ape::drop.tip( object@phylo, tip )
33 32
 
34
-			# add a colmn that has labels for both tips and internal nodes
35
-			object@nhx_tags$node.label = c(object@phylo$tip.label, as.character(object@phylo$node.label))
33
+              ## Subsample the tags
34
+              object@nhx_tags = object@nhx_tags[object@nhx_tags$node.label %in% (c(object@phylo$tip.label, as.character(object@phylo$node.label))),]
36 35
 
37
-			# Will need to take different approaches for subsampling tips 
38
-			# and internal nodes, add a column to make it easy to tell them apart
39
-			object@nhx_tags$is_tip = object@nhx_tags$node <= length(object@phylo$tip.label)
36
+              ## Update tip node numbers
37
+              tip_nodes <- object@nhx_tags$node.label[ object@nhx_tags$is_tip ]
38
+              internal_nodes <- object@nhx_tags$node.label[ !object@nhx_tags$is_tip ]
39
+              object@nhx_tags$node[ object@nhx_tags$is_tip ] = match(object@phylo$tip.label, tip_nodes)
40
+              object@nhx_tags$node[ !object@nhx_tags$is_tip ] = match(object@phylo$node.label, internal_nodes)
40 41
 
41
-			# Remove tips
42
-			object@phylo = ape::drop.tip( object@phylo, tip )
42
+              ## Clean up
43
+              object@nhx_tags$node.label = NULL
44
+              object@nhx_tags$is_tip = NULL
45
+              if (no_node_label) {
46
+                  object@phylo$node.label <- NULL
47
+              }
43 48
 
44
-			# Subsample the tags
45
-			object@nhx_tags = object@nhx_tags[object@nhx_tags$node.label %in% (c(object@phylo$tip.label, as.character(object@phylo$node.label))),]
49
+              return(object)
50
+          })
46 51
 
47
-			# Update tip node numbers
48
-			tip_nodes = object@nhx_tags$node.label[ object@nhx_tags$is_tip ]
49
-			object@nhx_tags$node[ object@nhx_tags$is_tip ] = match(object@phylo$tip.label, tip_nodes)
50 52
 
51
-			# Clean up
52
-			object@nhx_tags$node.label = NULL
53
-			object@nhx_tags$is_tip = NULL
54 53
 
55 54
 
56
-            return(object)
57
-		})
55
+
56
+##' @rdname drop.tip-methods
57
+##' @exportMethod drop.tip
58
+##' @aliases drop.tip,phylo
59
+##' @source
60
+##' drop.tip for phylo object is a wrapper method of ape::drop.tip
61
+##' from the ape package. The documentation you should
62
+##' read for the drop.tip function can be found here: \link[ape]{drop.tip}
63
+##'
64
+##' @seealso
65
+##' \link[ape]{drop.tip}
66
+setMethod("drop.tip", signature(object="phylo"),
67
+          function(object, tip, ...){
68
+              ape::drop.tip(object, tip, ...)
69
+          })
... ...
@@ -1,6 +1,6 @@
1
-##' plots simultaneously a whole phylogenetic tree and a portion of it. 
1
+##' plots simultaneously a whole phylogenetic tree and a portion of it.
2
+##'
2 3
 ##'
3
-##' 
4 4
 ##' @title gzoom
5 5
 ##' @param phy phylo object
6 6
 ##' @param focus selected tips
... ...
@@ -9,7 +9,6 @@
9 9
 ##' @return a list of ggplot object
10 10
 ##' @importFrom ggplot2 xlim
11 11
 ##' @importFrom ggplot2 scale_color_manual
12
-##' @importFrom ape drop.tip
13 12
 ##' @author ygc
14 13
 ##' @examples
15 14
 ##' require(ape)
... ...
@@ -28,14 +27,14 @@ gzoom.phylo <- function(phy, focus, subtree=FALSE, widths=c(.3, .7)) {
28 27
     cols <- c("black", "red")[foc+1]
29 28
 
30 29
     p1 <- ggtree(phy, color=cols)
31
-    
30
+
32 31
     subtr <- drop.tip(phy, phy$tip.label[-focus],
33 32
                       subtree=subtree, rooted=TRUE)
34
-    
33
+
35 34
     p2 <- ggtree(subtr, color="red") + geom_tiplab(hjust=-0.05)
36 35
     p2 <- p2 + xlim(0, max(p2$data$x)*1.2)
37
-    multiplot(p1, p2, ncol=2, widths=widths) 
38
-    
36
+    multiplot(p1, p2, ncol=2, widths=widths)
37
+
39 38
     invisible(list(p1=p1, p2=p2))
40 39
 }
41 40
 
... ...
@@ -68,7 +67,7 @@ setMethod("gzoom", signature(object="apeBootstrap"),
68 67
 
69 68
 ##' zoom selected subtree
70 69
 ##'
71
-##' 
70
+##'
72 71
 ##' @rdname gzoom-methods
73 72
 ##' @exportMethod gzoom
74 73
 setMethod("gzoom", signature(object="beast"),
... ...
@@ -1,8 +1,8 @@
1 1
 ##' site mask
2 2
 ##'
3
-##' 
3
+##'
4 4
 ##' @title mask
5
-##' @param tree_object tree object 
5
+##' @param tree_object tree object
6 6
 ##' @param field selected field
7 7
 ##' @param site site
8 8
 ##' @param mask_site if TRUE, site will be masked.
... ...
@@ -38,15 +38,15 @@ mask <- function(tree_object, field, site, mask_site=FALSE) {
38 38
         gsub("^[a-zA-Z]+", "", . ) %>%
39 39
         gsub("[a-zA-Z]\\s*$", "", .) %>%
40 40
         as.numeric
41
-    
41
+
42 42
     if (mask_site == FALSE) {
43 43
         pos2 <- 1:max(pos)
44 44
         pos2 <- pos2[-site]
45 45
         site <- pos2
46 46
     }
47
-    
47
+
48 48
     site <- site[site %in% pos]
49
-    
49
+
50 50
     for (i in seq_along(field_data)) {
51 51
         if (is.na(field_data[i]))
52 52
             next
... ...
@@ -95,7 +95,7 @@ read.dnds_mlc <- function(mlcfile) {
95 95
     mlc <- readLines(mlcfile)
96 96
     i <- grep("dN & dS for each branch", mlc)
97 97
     j <- grep("tree length for dN", mlc)
98
-    
98
+
99 99
     mlc <- mlc[i:j]
100 100
     hi <- grep("dN/dS", mlc)
101 101
     cn <- strsplit(mlc[hi], " ") %>% unlist %>% `[`(nzchar(.))
... ...
@@ -110,14 +110,14 @@ read.dnds_mlc <- function(mlcfile) {
110 110
         yy <- c(edge, y[-1])
111 111
         as.numeric(yy)
112 112
     }))
113
-             
113
+
114 114
     row.names(res) <- NULL
115 115
     colnames(res) <- c("parent", "node", cn[-1])
116 116
     colnames(res) <- gsub("\\*", "_x_", colnames(res))
117 117
     colnames(res) <- gsub("\\/", "_vs_", colnames(res))
118 118
     return(res)
119 119
 }
120
-    
120
+
121 121
 read.treetext_paml_mlc <- function(mlcfile) {
122 122
     read.treetext_paml(mlcfile, "mlc")
123 123
 }
... ...
@@ -138,14 +138,13 @@ read.treetext_paml <- function(file, by) {
138 138
     } else {
139 139
         stop("_by_ should be one of 'rst' or 'mlc'")
140 140
     }
141
-        
141
+
142 142
     return(x[tr.idx][ii])
143 143
 }
144 144
 
145
-##' @importFrom ape Ntip
146 145
 read.phylo_paml_mlc <- function(mlcfile) {
147 146
     parent <- node <- label <- NULL
148
-    
147
+
149 148
     mlc <- readLines(mlcfile)
150 149
     edge <- get_tree_edge_paml(mlc)
151 150
 
... ...
@@ -189,7 +188,7 @@ read.phylo_paml_mlc <- function(mlcfile) {
189 188
                 }
190 189
                 treeinfo[ii, "visited"] <- TRUE
191 190
             }
192
-            
191
+
193 192
         }
194 193
         currentNode <- unique(pNode)
195 194
     }
... ...
@@ -211,7 +210,7 @@ read.phylo_paml_mlc <- function(mlcfile) {
211 210
 ##' @importFrom ape reorder.phylo
212 211
 read.phylo_paml_rst <- function(rstfile) {
213 212
     parent <- node <- label <- NULL
214
-    
213
+
215 214
     ## works fine with baseml and codeml
216 215
     rst <- readLines(rstfile)
217 216
     tr.idx <- get_tree_index_paml(rst)
... ...
@@ -220,7 +219,7 @@ read.phylo_paml_rst <- function(rstfile) {
220 219
     tr3 <- read.tree(text=rst[tr.idx][3])
221 220
 
222 221
     edge <- get_tree_edge_paml(rst)
223
-    
222
+
224 223
     label=c(tr3$tip.label, tr3$node.label)
225 224
     root <- getRoot(tr3)
226 225
     label %<>% `[`(. != root)
... ...
@@ -231,14 +230,14 @@ read.phylo_paml_rst <- function(rstfile) {
231 230
     ## node.length$node <- sub("_\\w+", "", node.length$label
232 231
     node.length$node <- gsub("^(\\d+)_.*", "\\1", node.length$label)
233 232
     node.length$label %<>% sub("\\d+_", "", .)
234
-    
233
+
235 234
     edge <- as.data.frame(edge)
236 235
     colnames(edge) <- c("parent", "node")
237 236
 
238 237
     treeinfo <- merge(edge, node.length, by.x="node", by.y="node")
239 238
     edge2 <- treeinfo[, c("parent", "node")]
240 239
     edge2 %<>% as.matrix
241
-    
240
+
242 241
     ntip <- Ntip(tr3)
243 242
 
244 243
     phylo <- with(treeinfo,
... ...
@@ -253,7 +252,7 @@ read.phylo_paml_rst <- function(rstfile) {
253 252
 
254 253
     class(phylo) <- "phylo"
255 254
     phylo <- reorder.phylo(phylo, "cladewise")
256
-    
255
+
257 256
     return(phylo)
258 257
 }
259 258
 
... ...
@@ -262,10 +261,10 @@ read.ancseq_paml_rst <- function(rstfile, by="Marginal") {
262 261
     rst <- readLines(rstfile)
263 262
 
264 263
     by <- match.arg(by, c("Marginal", "Joint"))
265
-    query <- paste(by, "reconstruction of ancestral sequences") 
264
+    query <- paste(by, "reconstruction of ancestral sequences")
266 265
     idx <- grep(query, rst)
267 266
     if(length(idx) == 0) {
268
-        ## in some paml setting, joint_ancseq are not available. 
267
+        ## in some paml setting, joint_ancseq are not available.
269 268
         return("")
270 269
     }
271 270
     si <- grep("reconstructed sequences", rst)
... ...
@@ -323,13 +322,13 @@ set.paml_rst_ <- function(object) {
323 322
     if (length(object@tip_seq) == 0) {
324 323
         return(object)
325 324
     }
326
-    
325
+
327 326
     types <- get.fields(object)
328 327
     for (type in types) {
329 328
         value <- subs_paml_rst(object, type)
330 329
         if (all(is.na(value)))
331 330
             next
332
-        
331
+
333 332
         if (type == "marginal_subs") {
334 333
             object@marginal_subs <- value
335 334
         } else if (type == "marginal_AA_subs") {
... ...
@@ -1,3 +1,16 @@
1
+Ntip <- function(tree) {
2
+    phylo <- get.tree(tree)
3
+    length(phylo$tip.label)
4
+}
5
+
6
+Nnode <- function(tree, internal.only=TRUE) {
7
+    phylo <- get.tree(tree)
8
+    if (internal.only)
9
+        return(phylo$Nnode)
10
+
11
+    Ntip(phylo) + phylo$Nnode
12
+}
13
+
1 14
 
2 15
 filename <- function(file) {
3 16
     ## textConnection(text_string) will work just like a file
... ...
@@ -12,7 +25,7 @@ filename <- function(file) {
12 25
 
13 26
 ##' @importFrom ggplot2 last_plot
14 27
 get_tree_view <- function(tree_view) {
15
-    if (is.null(tree_view)) 
28
+    if (is.null(tree_view))
16 29
         tree_view <- last_plot()
17 30
 
18 31
     return(tree_view)
... ...
@@ -33,7 +46,7 @@ has.field <- function(tree_object, field) {
33 46
     if ( ! field %in% get.fields(tree_object) ) {
34 47
         return(FALSE)
35 48
     }
36
-    
49
+
37 50
     if (is(tree_object, "codeml")) {
38 51
         is_codeml <- TRUE
39 52
         tree <- tree_object@rst
... ...
@@ -41,22 +54,22 @@ has.field <- function(tree_object, field) {
41 54
         is_codeml <- FALSE
42 55
         tree <- tree_object
43 56
     }
44
-    
57
+
45 58
     if (.hasSlot(tree, field)) {
46 59
         has_slot <- TRUE
47 60
     } else {
48 61
         has_slot <- FALSE
49 62
     }
50
-    
63
+
51 64
     if (has_slot == FALSE) {
52 65
         if (has.extraInfo(tree_object) == FALSE) {
53 66
             return(FALSE)
54 67
         }
55
-        
68
+
56 69
         if (nrow(tree_object@extraInfo) == 0) {
57 70
             return(FALSE)
58 71
         }
59
-        
72
+
60 73
         if (!field %in% colnames(tree_object@extraInfo)) {
61 74
             return(FALSE)
62 75
         }
... ...
@@ -82,7 +95,7 @@ has.extraInfo <- function(object) {
82 95
         return(TRUE)
83 96
     }
84 97
 
85
-    return(FALSE)        
98
+    return(FALSE)
86 99
 }
87 100
 
88 101
 append_extraInfo <- function(df, object) {
... ...
@@ -110,7 +123,7 @@ get.fields.tree <- function(object) {
110 123
     } else {
111 124
         fields <- object@fields
112 125
     }
113
-    
126
+
114 127
     if (has.slot(object, "extraInfo")) {
115 128
         extraInfo <- object@extraInfo
116 129
         if (nrow(extraInfo) > 0) {
... ...
@@ -124,7 +137,7 @@ get.fields.tree <- function(object) {
124 137
 }
125 138
 
126 139
 print_fields <- function(object, len=5) {
127
-    fields <- get.fields(object)    
140
+    fields <- get.fields(object)
128 141
     n <- length(fields)
129 142
     i <- floor(n/len)
130 143
     for (j in 0:i) {
... ...
@@ -158,7 +171,7 @@ plot.subs <- function(x, layout, show.tip.label,
158 171
                       position, annotation,
159 172
                       annotation.color = "black",
160 173
                       annotation.size=3, ...) {
161
-    
174
+
162 175
     p <- ggtree(x, layout=layout, ...)
163 176
     if (show.tip.label) {
164 177
         p <- p + geom_tiplab(hjust = tip.label.hjust,
... ...
@@ -174,7 +187,7 @@ plot.subs <- function(x, layout, show.tip.label,
174 187
 
175 188
 .add_new_line <- function(res) {
176 189
     ## res <- paste0(strwrap(res, 50), collapse="\n")
177
-    ## res %<>% gsub("\\s/\n", "\n", .) %>% gsub("\n/\\s", "\n", .) 
190
+    ## res %<>% gsub("\\s/\n", "\n", .) %>% gsub("\n/\\s", "\n", .)
178 191
     if (nchar(res) > 50) {
179 192
         idx <- gregexpr("/", res)[[1]]
180 193
         i <- idx[floor(length(idx)/2)]
... ...
@@ -198,7 +211,7 @@ get.subs_ <- function(tree, fasta, translate=TRUE, removeGap=TRUE) {
198 211
         }
199 212
         .add_new_line(res)
200 213
     })
201
-    
214
+
202 215
     dd <- data.frame(node=node, parent=parent, label=label, subs=subs)
203 216
     dd <- dd[dd$parent != 0,]
204 217
     dd <- dd[, -c(1,2)]
... ...
@@ -214,7 +227,7 @@ getSubsLabel <- function(seqs, A, B, translate, removeGap) {
214 227
     if (nchar(seqA) != nchar(seqB)) {
215 228
         stop("seqA should have equal length to seqB")
216 229
     }
217
-    
230
+
218 231
     if (translate == TRUE) {
219 232
         AA <- seqA %>% seq2codon %>% codon2AA
220 233
         BB <- seqB %>% seq2codon %>% codon2AA
... ...
@@ -227,7 +240,7 @@ getSubsLabel <- function(seqs, A, B, translate, removeGap) {
227 240
         AA <- strsplit(seqA, split="") %>% unlist
228 241
         BB <- strsplit(seqB, split="") %>% unlist
229 242
     }
230
-    
243
+
231 244
     ii <- which(AA != BB)
232 245
 
233 246
     if (removeGap == TRUE) {
... ...
@@ -239,11 +252,11 @@ getSubsLabel <- function(seqs, A, B, translate, removeGap) {
239 252
             ii <- ii[AA[ii] != "-" & BB[ii] != "-"]
240 253
         }
241 254
     }
242
-    
255
+
243 256
     if (length(ii) == 0) {
244 257
         return(NULL)
245 258
     }
246
-    
259
+
247 260
     res <- paste(AA[ii], ii, BB[ii], sep="", collapse=" / ")
248 261
     return(res)
249 262
 }
... ...
@@ -255,7 +268,7 @@ seq2codon <- function(x) {
255 268
 ## @importFrom Biostrings GENETIC_CODE
256 269
 codon2AA <- function(codon) {
257 270
     ## a genetic code name vector
258
-    GENETIC_CODE <- get_fun_from_pkg("Biostrings", "GENETIC_CODE") 
271
+    GENETIC_CODE <- get_fun_from_pkg("Biostrings", "GENETIC_CODE")
259 272
     aa <- GENETIC_CODE[codon]
260 273
     aa[is.na(aa)] <- "X"
261 274
     return(aa)
... ...
@@ -327,22 +340,22 @@ jplace_treetext_to_phylo <- function(tree.text) {
327 340
     ##                         edgeNum = as.numeric(gsub(".+\\{", "", edgeLN)))
328 341
 
329 342
     ## xx <- merge(edgeLN.df, edgeNum.df, by.x="node", by.y="node")
330
-    
343
+
331 344
     return(phylo)
332 345
 }
333 346
 
334 347
 extract.treeinfo.jplace <- function(object, layout="phylogram", ladderize=TRUE, right=FALSE, ...) {
335 348
 
336 349
     tree <- get.tree(object)
337
-    
350
+
338 351
     df <- fortify.phylo(tree, layout=layout, ladderize=ladderize, right=right, ...)
339 352
 
340 353
     edgeNum.df <- attr(tree, "edgeNum")
341 354
     if (!is.null(edgeNum.df)) {
342
-        df2 <- merge(df, edgeNum.df, by.x="node", by.y="node", all.x=TRUE) 
355
+        df2 <- merge(df, edgeNum.df, by.x="node", by.y="node", all.x=TRUE)
343 356
         df <- df2[match(df[, "node"], df2[, "node"]),]
344 357
     }
345
-    
358
+
346 359
     attr(df, "ladderize") <- ladderize
347 360
     attr(df, "right") <- right
348 361
     return(df)
... ...
@@ -356,7 +369,7 @@ edgeNum2nodeNum <- function(jp, edgeNum) {
356 369
     if (length(idx) == 0) {
357 370
         return(NA)
358 371
     }
359
-    
372
+
360 373
     edges[idx, "node"]
361 374
 }
362 375
 
... ...
@@ -427,7 +440,7 @@ is.tree_attribute <- function(df, var) {
427 440
        !is.null(var)    &&
428 441
        var %in% colnames(df)) {
429 442
         return(TRUE)
430
-    } 
443
+    }
431 444
     return(FALSE)
432 445
 }
433 446
 
... ...
@@ -483,14 +496,14 @@ roundDigit <- function(d) {
483 496
 ## from ChIPseeker
484 497
 ##' @importFrom grDevices colorRampPalette
485 498
 getCols <- function (n) {
486
-    col <- c("#8dd3c7", "#ffffb3", "#bebada", "#fb8072", "#80b1d3", 
487
-             "#fdb462", "#b3de69", "#fccde5", "#d9d9d9", "#bc80bd", 
499
+    col <- c("#8dd3c7", "#ffffb3", "#bebada", "#fb8072", "#80b1d3",
500
+             "#fdb462", "#b3de69", "#fccde5", "#d9d9d9", "#bc80bd",
488 501
              "#ccebc5", "#ffed6f")
489
-    col2 <- c("#1f78b4", "#ffff33", "#c2a5cf", "#ff7f00", "#810f7c", 
490
-              "#a6cee3", "#006d2c", "#4d4d4d", "#8c510a", "#d73027", 
502
+    col2 <- c("#1f78b4", "#ffff33", "#c2a5cf", "#ff7f00", "#810f7c",
503
+              "#a6cee3", "#006d2c", "#4d4d4d", "#8c510a", "#d73027",
491 504
               "#78c679", "#7f0000", "#41b6c4", "#e7298a", "#54278f")
492
-    col3 <- c("#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99", 
493
-              "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a", 
505
+    col3 <- c("#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99",
506
+              "#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a",
494 507
               "#ffff99", "#b15928")
495 508
     colorRampPalette(col3)(n)
496 509
 }
... ...
@@ -3,7 +3,7 @@ ggtree: an R package for visualization and annotation of phylogenetic trees with
3 3
 
4 4
 [![releaseVersion](https://img.shields.io/badge/release%20version-1.6.2-green.svg?style=flat)](https://bioconductor.org/packages/ggtree) [![develVersion](https://img.shields.io/badge/devel%20version-1.7.3-green.svg?style=flat)](https://github.com/GuangchuangYu/ggtree) [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#since) [![total](https://img.shields.io/badge/downloads-16443/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1621/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree)
5 5
 
6
-[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) [![codecov](https://codecov.io/gh/GuangchuangYu/ggtree/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/ggtree) [![Last-changedate](https://img.shields.io/badge/last%20change-2016--11--10-green.svg)](https://github.com/GuangchuangYu/ggtree/commits/master) [![GitHub forks](https://img.shields.io/github/forks/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/network) [![GitHub stars](https://img.shields.io/github/stars/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/stargazers) [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://awesome-r.com/#awesome-r-graphic-displays)
6
+[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) [![codecov](https://codecov.io/gh/GuangchuangYu/ggtree/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/ggtree) [![Last-changedate](https://img.shields.io/badge/last%20change-2016--11--11-green.svg)](https://github.com/GuangchuangYu/ggtree/commits/master) [![GitHub forks](https://img.shields.io/github/forks/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/network) [![GitHub stars](https://img.shields.io/github/stars/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/stargazers) [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://awesome-r.com/#awesome-r-graphic-displays)
7 7
 
8 8
 [![platform](http://www.bioconductor.org/shields/availability/devel/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#archives) [![Build Status](http://www.bioconductor.org/shields/build/devel/bioc/ggtree.svg)](https://bioconductor.org/checkResults/devel/bioc-LATEST/ggtree/) [![Linux/Mac Travis Build Status](https://img.shields.io/travis/GuangchuangYu/ggtree/master.svg?label=Mac%20OSX%20%26%20Linux)](https://travis-ci.org/GuangchuangYu/ggtree) [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/Guangchuangyu/ggtree/master.svg?label=Windows)](https://ci.appveyor.com/project/GuangchuangYu/ggtree) [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-green.svg?style=flat)](http://bioconda.github.io/recipes/bioconductor-ggtree/README.html)
9 9
 
... ...
@@ -1,17 +1,42 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/method-drop-tip.R
2
+% Please edit documentation in R/AllGenerics.R, R/method-drop-tip.R
3 3
 \docType{methods}
4 4
 \name{drop.tip}
5 5
 \alias{drop.tip}
6 6
 \alias{drop.tip,nhx}
7
+\alias{drop.tip,nhx-method}
8
+\alias{drop.tip,phylo}
9
+\alias{drop.tip,phylo-method}
7 10
 \title{drop.tip method}
11
+\source{
12
+drop.tip for phylo object is a wrapper method of ape::drop.tip
13
+from the ape package. The documentation you should
14
+read for the drop.tip function can be found here: \link[ape]{drop.tip}
15
+}
8 16
 \usage{
9
-drop.tip(object, tip...)
17
+drop.tip(object, tip, ...)
18
+
19
+drop.tip(object, tip, ...)
20
+
21
+\S4method{drop.tip}{phylo}(object, tip, ...)
22
+}
23
+\arguments{
24
+\item{object}{An nhx or phylo object}
25
+
26
+\item{tip}{a vector of mode numeric or character specifying the tips to delete}
27
+
28
+\item{...}{additional parameters}
29
+}
30
+\value{
31
+updated object
10 32
 }
11 33
 \description{
12 34
 drop.tip method
13 35
 }
14 36
 \author{
15
-Casey Dunn \url{http://dunnlab.org}
37
+Casey Dunn \url{http://dunnlab.org}  and Guangchuang Yu \url{https://guangchuangyu.github.io}
38
+}
39
+\seealso{
40
+\link[ape]{drop.tip}
16 41
 }
17 42
 
18 43
deleted file mode 100644
... ...
@@ -1,18 +0,0 @@
1
-% Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/method-drop-tip.R
3
-\name{drop.tip}
4
-\alias{drop.tip}
5
-\title{Drop a tip}
6
-\usage{
7
-drop.tip(object, ...)
8
-}
9
-\arguments{
10
-\item{object}{An nhx object}
11
-}
12
-\value{
13
-An nhx object
14
-}
15
-\description{
16
-Drop a tip
17
-}
18
-
... ...
@@ -7,16 +7,16 @@ test_phyldog_nhx_text = "(((Prayidae_D27SS7@2825365:0.0682841[&&NHX:Ev=S:S=58:ND
7 7
 
8 8
 test_notung_nhx_text = "((((Rhizophysa_filiformis@2564549:0.09666991738603078[&&NHX:S=Rhizophysa_filiformis],((Marrus_claudanielis@2027078:0.03368582974818837[&&NHX:S=Marrus_claudanielis],((Erenna_richardi@1434201:0.014306889954561298[&&NHX:S=Erenna_richardi],Marrus_claudanielis@2027079:0.010842363778569869[&&NHX:S=Marrus_claudanielis])n5940011:0.01779384958849464[&&NHX:S=n57:D=N],(((Agalma_elegans@88626:0.05872379503260147[&&NHX:S=Agalma_elegans],Lychnagalma_utricularia@1828459:0.04211137470826968[&&NHX:S=Lychnagalma_utricularia])n5940018:0.02375590664436535[&&NHX:S=n47:D=N],(((Bargmannia_amoena@3459111:0.19058396964770352[&&NHX:S=Bargmannia_amoena],Bargmannia_elongata@469437:1.00000050002909E-6[&&NHX:S=Bargmannia_elongata])n5939974:0.11560220708003867[&&NHX:S=n22:D=N],Cordagalma_sp_@1115328:0.04829417133033771[&&NHX:S=Cordagalma_sp_])n5939976:0.011316847557531757[&&NHX:S=n62:D=N],Forskalia_asymmetrica@1220430:0.01667566952752948[&&NHX:S=Forskalia_asymmetrica])n5939978:0.0063213422810751655[&&NHX:S=n62:D=Y])n5940014:0.017792661031819083[&&NHX:S=n62:D=Y],(Resomia_ornicephala@2657185:0.004262563771468986[&&NHX:S=Resomia_ornicephala],Frillagalma_vityazi@663744:0.028441637105547157[&&NHX:S=Frillagalma_vityazi])n5939981:0.006136291467151878[&&NHX:S=n51:D=N])n5940013:0.013546839136761205[&&NHX:S=n62:D=Y])n5940012:0.011839606018978143[&&NHX:S=n62:D=Y])n5940008:0.013840645450221475[&&NHX:S=n62:D=Y],(((Chelophyes_appendiculata@1615707:0.007647023552225329[&&NHX:S=Chelophyes_appendiculata],Clytia_hemisphaerica@756642:0.643907456299178[&&NHX:S=Clytia_hemisphaerica])n5939984:0.08603691877960613[&&NHX:S=n67:D=N],(Chuniphyes_multidentata@930929:0.01248550133310033[&&NHX:S=Chuniphyes_multidentata],Kephyes_ovata@1966030:0.014671165587181996[&&NHX:S=Kephyes_ovata])n5939987:0.013285803501636162[&&NHX:S=n27:D=N])n5939988:0.008000411801689693[&&NHX:S=n67:D=Y],(((Hippopodius_hippopus@1084434:0.0505718831943577[&&NHX:S=Hippopodius_hippopus],Prayidae_D27D2@2878798:0.00905875758406546[&&NHX:S=Prayidae_D27D2])n5939991:0.021772123626769023[&&NHX:S=n38:D=N],Prayidae_D27SS7@2181711:0.029009000260863272[&&NHX:S=Prayidae_D27SS7])n5939993:1.00000050002909E-6[&&NHX:S=n38:D=Y],Prayidae_D27D2@2878801:1.00000050002909E-6[&&NHX:S=Prayidae_D27D2])n5939995:0.00916688375355408[&&NHX:S=n38:D=Y])n5939996:0.05191099091093772[&&NHX:S=n67:D=Y])n5940006:0.03953811931719265[&&NHX:S=n67:D=Y])n5940005:0.10134081070615458[&&NHX:S=n67:D=Y],(Podocoryna_carnea@3033951:0.11270255504816476[&&NHX:S=Podocoryna_carnea],Hydractinia_symbiolongicarpus@1679508:0.030168043235021993[&&NHX:S=Hydractinia_symbiolongicarpus])n5939999:0.17223048099362362[&&NHX:S=n11:D=N])n5940003:0.16233679521228994[&&NHX:S=n67:D=Y],Hydra_magnipapillata@801936:0.585696573276294[&&NHX:S=Hydra_magnipapillata])n5940002:0.4403044529817829[&&NHX:S=n68:D=N],Aegina_citrea@825314:0.4403044529817829[&&NHX:S=Aegina_citrea])n5942419[&&NHX:S=n70:D=N];"
9 9
 
10
-# A function to simplify NHX text so that it can be parsed by 
11
-# ape::read.tree(). Discards much useful information. Intent is to 
10
+# A function to simplify NHX text so that it can be parsed by
11
+# ape::read.tree(). Discards much useful information. Intent is to
12 12
 # be able to compare node annotations that have been independently
13
-# parsed with different methods. 
13
+# parsed with different methods.
14 14
 simplify_nhx_string <- function( text ){
15 15
 	# Remove branch lengths so NHX tags are adjacent to nodes
16 16
 	# Accommodate lengths in scientific notation, eg 1e-6
17 17
 	text = gsub( "\\:[\\d\\.]+e[\\d\\-]+","", text, perl=TRUE )
18 18
 	text = gsub( "\\:[\\d\\.]+","", text, perl=TRUE )
19
-	
19
+
20 20
 	# Remove NHX tags at tips
21 21
 	text = gsub( "([^\\)])\\[.+?\\]","\\1", text, perl=TRUE )
22 22
 
... ...
@@ -27,7 +27,7 @@ simplify_nhx_string <- function( text ){
27 27
 	# Replace NHX tag formatting characters that aren't allowed
28 28
 	text = gsub( ":","_", text, perl=TRUE )
29 29
 	text = gsub( "=","-", text, perl=TRUE )
30
-	
30
+
31 31
 	return(text)
32 32
 }
33 33
 
... ...
@@ -78,8 +78,9 @@ test_that("can parse phyldog nhx tree string", {
78 78
 
79 79
 test_that("can drop tips", {
80 80
 	nhx <- read.nhx( textConnection(test_phyldog_nhx_text) )
81
-		to_drop = c("Physonect_sp_@2066767", "Lychnagalma_utricularia@2253871", "Kephyes_ovata@2606431")
82
-	
81
+        to_drop = c("Physonect_sp_@2066767", "Lychnagalma_utricularia@2253871", "Kephyes_ovata@2606431")
82
+
83 83
 	nhx_reduced = drop.tip(nhx, to_drop)
84 84
 	expect_equal( length(nhx_reduced@phylo$tip.label), 13 )
85
-})
86 85
\ No newline at end of file
86
+        expect_true( all(nhx_reduced@nhx_tags$node %in% fortify(nhx_reduced)$node) )
87
+})