遍历multiPhylo对象:为何`1:length(trees)`写法可行?
Let's break down the core reasons behind this behavior, plus why your first dataset worked with code block (a):
1. The Key Difference: How R Iterates Over multiPhylo Objects
The multiPhylo class from the ape package is essentially a list of phylo objects, but it has special subsetting behavior:
trees[i]returns a smaller multiPhylo object containing just the i-th tree (not a singlephyloobject)trees[[i]]returns the i-th tree as a standalonephyloobject
What's happening in Code Block (a)
When you use for(tree in trees), R may use the [ operator under the hood for some multiPhylo objects. That means each tree variable in the loop is actually a tiny multiPhylo object (with one tree) instead of a single phylo object.
While ape::drop.tip() can handle multiPhylo inputs, in some cases (like your first dataset's structure or specific ape version), the modified tree might not be correctly extracted when writing to file. This leads to output files that still contain the original tree (hence your "invalid" result).
What's happening in Code Block (b)
By looping over indices and using trees[[tree]], you explicitly grab a single phylo object each time. This is the input type drop.tip() is designed for, so the modification works reliably, and writing the resulting phylo object to file behaves exactly as expected.
2. Why Your First Dataset Worked with Code Block (a)
Not all multiPhylo objects are created equal:
- The second dataset you used (from the Glottolog tree file) was likely parsed into a
multiPhyloobject where iterating withfor(tree in trees)returns individualphyloobjects directly. This could be due to differences in how the original file was formatted (Newick vs. Nexus) or howapeparsed its structure. - In contrast, the Gray et al. 2009 dataset's Nexus file might have metadata or formatting that makes
apetreat themultiPhyloobject differently during iteration.
Quick Verification Steps
To confirm this is the issue, add a line to check the class of tree in each loop iteration:
# Add to Code Block (a) for(tree in trees){ index <- index +1 print(class(tree)) # Check if this is "phylo" or "multiPhylo" tree <- ape::drop.tip(tree, tip_to_drop) output_fn <- paste0("tree_", index, ".txt") write.nexus(tree,file = output_fn ) }
If you see "multiPhylo" in the output, that's exactly the problem we described.
Also, note that your original GitHub URL points to a web page, not the raw data file. You'll need to use the raw URL for read.nexus() to work correctly:
fn <- "https://raw.githubusercontent.com/D-PLACE/dplace-data/master/phylogenies/gray_et_al2009/original/a400-m1pcv-time.trees.gz"
内容的提问来源于stack exchange,提问作者Laserhedvig

