@@ -541,46 +541,54 @@ new_phylotax_env <- function(tree, taxa, parent = parent.frame()) {
541
541
.parent = parent ,
542
542
node_taxa = tibble :: tibble(
543
543
node = integer(),
544
+ label = NULL ,
544
545
rank = taxa $ rank [FALSE ],
545
546
taxon = character ()
546
547
),
547
- tip_taxa = dplyr :: filter(taxa , .data $ label %in% tree $ tip.label ),
548
+ tip_taxa = dplyr :: filter(taxa , FALSE ),
549
+ retained = dplyr :: filter(taxa , .data $ label %in% tree $ tip.label ),
550
+ rejected = dplyr :: filter(taxa , FALSE ),
551
+ missing = dplyr :: filter(taxa , ! .data $ label %in% tree $ tip.label ),
548
552
tree = tree
549
553
)
550
554
}
551
555
552
556
553
557
phylotax_ <- function (tree , taxa , node , ranks , method , e ) {
554
558
if (length(ranks ) == 0 ) return ()
555
-
559
+ nodelabel <- if (! is.null(tree $ node.label )) {
560
+ tree $ node.label [node - ape :: Ntip(tree )]
561
+ } else {
562
+ as.character(node )
563
+ }
556
564
parents <- phangorn :: Ancestors(tree , node , type = " all" )
557
565
for (r in ranks ) {
558
566
if (is.ordered(ranks )) r <- ordered(r , levels = levels(ranks ))
559
567
if (any(e $ node_taxa $ node %in% parents & e $ node_taxa $ rank == r )) next
560
- taxon <- clade_taxon(tree , e $ tip_taxa , node , r )
568
+ taxon <- clade_taxon(tree , e $ retained , node , r )
561
569
if (is.na(taxon )) {
562
- futile.logger :: flog.debug(" Could not assign a %s to node %d ." , r , node )
570
+ futile.logger :: flog.debug(" Could not assign a %s to node %s ." , r , nodelabel )
563
571
for (n in phangorn :: Children(tree , node )) {
564
- phylotax_(tree , e $ tip_taxa , n , ranks , method , e )
572
+ phylotax_(tree , e $ retained , n , ranks , method , e )
565
573
}
566
574
break
567
575
} else {
568
576
children <- phangorn :: Children(tree , node )
569
577
if (length(children ) > 0 ) {
570
578
futile.logger :: flog.info(
571
- " Assigned node %d and its %d children to %s %s." ,
572
- node , length(children ), as.character(r ), taxon )
579
+ " Assigned node %s and its %d children to %s %s." ,
580
+ nodelabel , length(children ), as.character(r ), taxon )
573
581
} else {
574
- futile.logger :: flog.info(" Assigned node %d to %s %s." , node ,
582
+ futile.logger :: flog.info(" Assigned node %s to %s %s." , nodelabel ,
575
583
as.character(r ), taxon )
576
584
}
577
585
ranks <- ranks [- 1 ]
578
586
e $ node_taxa <- dplyr :: bind_rows(
579
587
e $ node_taxa ,
580
- tibble :: tibble(node = node , rank = r , taxon = taxon )
588
+ tibble :: tibble(node = node , label = nodelabel , rank = r , taxon = taxon )
581
589
)
582
590
tips <- tree $ tip.label [phangorn :: Descendants(tree , node , type = " tips" )[[1 ]]]
583
- wrongTaxa <- e $ tip_taxa %> %
591
+ wrongTaxa <- e $ retained %> %
584
592
dplyr :: filter(
585
593
.data $ label %in% tips ,
586
594
.data $ rank == r ,
@@ -596,11 +604,16 @@ phylotax_ <- function(tree, taxa, node, ranks, method, e) {
596
604
newAssign [[n ]] <- unname(method [n ])
597
605
}
598
606
# remove assignments which are not consistent with the one we just chose
599
- e $ tip_taxa <- dplyr :: bind_rows(
600
- dplyr :: filter(e $ tip_taxa , .data $ rank < r ),
601
- dplyr :: filter(e $ tip_taxa , .data $ rank > = r ) %> %
602
- dplyr :: anti_join(wrongTaxa , by = names(wrongTaxa )),
603
- newAssign
607
+ e $ tip_taxa <- dplyr :: bind_rows(e $ tip_taxa , newAssign )
608
+ e $ rejected <- dplyr :: bind_rows(
609
+ e $ rejected ,
610
+ dplyr :: filter(e $ retained , .data $ rank > = r ) %> %
611
+ dplyr :: semi_join(wrongTaxa , by = names(wrongTaxa ))
612
+ )
613
+ e $ retained <- dplyr :: bind_rows(
614
+ dplyr :: filter(e $ retained , .data $ rank < r ),
615
+ dplyr :: filter(e $ retained , .data $ rank > = r ) %> %
616
+ dplyr :: anti_join(wrongTaxa , by = names(wrongTaxa ))
604
617
)
605
618
}
606
619
}
@@ -647,14 +660,20 @@ phylotax_ <- function(tree, taxa, node, ranks, method, e) {
647
660
# ' treat each unique combination of values in these columns as a distinct
648
661
# ' method.
649
662
# '
650
- # ' @return a list with two elements, "tip_taxa" and "node_taxa". "tip_taxa" is
651
- # ' a `tibble::tibble()` with the same format as `taxa`, in
652
- # ' which assignments which are inconsistent with the phylogeny have been
653
- # ' removed, and new assignments deduced or confirmed from the phylogeny.
654
- # ' These are identified by the value "phylotax" in the "method" column,
655
- # ' which is created if it does not already exist. "node_taxa" has columns
656
- # ' "node", "rank" and "taxon", giving taxonomic assignments for the nodes of
657
- # ' the tree.
663
+ # ' @return an S3 object with class "`phylotax`", with five elements:
664
+ # ' * "`tip_taxa` a `tibble::tibble()` with the same format as `taxa`, containing
665
+ # ' taxonomy assignments made by PHYLOTAX to tips.
666
+ # ' * "`node_taxa`" a `tibble::tibble()` with columns "`node`", "`label`",
667
+ # ' "`rank`" and "`taxon`" giving taxonomy assignments made by PHYLOTAX to
668
+ # ' internal nodes.
669
+ # ' * "`rejected`" a `tibble::tibble()` with the same format as `taxa` giving
670
+ # ' primary assignments which have been rejected by PHYLOTAX.
671
+ # ' * "`retained`" a `tibble::tibble()` with the same format as `taxa` giving
672
+ # ' primary assignments which have not been rehected by PHYLOTAX. These may
673
+ # ' contain inconsistencies that PHYLOTAX was unable to resolve.
674
+ # ' * "`missing`" a `tibble::tibble()` with the same format as `taxa`, giving the
675
+ # ' primary assignments which have not been assessed by PHULOTAX because they
676
+ # ' have labels which are not present on the tree.
658
677
# '
659
678
# ' @export
660
679
phylotax <- function (
@@ -670,9 +689,13 @@ phylotax <- function(
670
689
e <- new_phylotax_env(tree , count_assignments(taxa ), ranks )
671
690
ranks <- sort(unique(taxa $ rank ))
672
691
phylotax_(tree , taxa , phangorn :: getRoot(tree ), ranks , method , e )
673
- e $ tip_taxa $ n_tot <- NULL
674
- e $ tip_taxa $ n_diff <- NULL
675
- as.list(e )
692
+ for (member in c(" missing" , " retained" , " rejected" , " tip_taxa" ))
693
+ for (n in c(" n_tot" , " n_diff" ))
694
+ e [[member ]][[n ]] <- NULL
695
+ structure(
696
+ as.list(e ),
697
+ class = " phylotax"
698
+ )
676
699
}
677
700
678
701
# ' Simple phylogenetic tree for use in examples
0 commit comments