Skip to content

Commit 985b925

Browse files
coraallensaviettacecileane
authored andcommitted
StatsModels v0.6.0 compatibility; REQUIRE -> Project.toml
also: - v0.9.1 and this commit not compatible with GLM v1.2.0+ would need to cap v0.9.1 to use GLM v1.1.1. - LinPredModel -> GLM.LinPredModel for compatibility with GLM v1.2.0+ - fitdiscrete: * better wrapper * empirical & stationary distributions * name change from fitDiscrete * rate variation: category median rates normalized * fixed SM traitlabels2indices error
1 parent 1431723 commit 985b925

16 files changed

+644
-384
lines changed

Project.toml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name = "PhyloNetworks"
2+
uuid = "33ad39ac-ed31-50eb-9b15-43d0656eaa72"
3+
license = "MIT"
4+
version = "0.10.0"
5+
6+
[deps]
7+
BioSequences = "7e6ae17a-c86d-528c-b3b9-7f778a29fe59"
8+
BioSymbols = "3c28c6f8-a34d-59c4-9654-267d177fcfa9"
9+
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
10+
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
11+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
12+
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
13+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
14+
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
15+
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
16+
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
17+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
18+
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd"
19+
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
20+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
21+
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
22+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
23+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
24+
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
25+
StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
26+
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
27+
28+
[compat]
29+
BioSequences = "≥ 1.0.0"
30+
BioSymbols = "≥ 3.0.0"
31+
CSV = "≥ 0.4.0"
32+
Combinatorics = "≥ 0.7.0"
33+
DataFrames = "≥ 0.13.0"
34+
DataStructures = "≥ 0.9.0"
35+
Distributions = "≥ 0.15.0"
36+
GLM = "≥ 1.0.0"
37+
NLopt = "≥ 0.5.1"
38+
SpecialFunctions = "≥ 0.7.0"
39+
StaticArrays = "≥ 0.8.3"
40+
StatsBase = "≥ 0.26.0"
41+
StatsFuns = "≥ 0.7.0"
42+
StatsModels = "≥ 0.6.0"
43+
julia = "≥ 0.7.0"
44+
45+
[extras]
46+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
47+
48+
[targets]
49+
test = ["Test"]

REQUIRE

-15
This file was deleted.

benchmark/benchmarks.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const SUITE = BenchmarkGroup()
99

1010
SUITE["nasm"] = BenchmarkGroup(["JC69", "HKY85"])
1111
SUITE["fitDiscreteFixed"] = BenchmarkGroup(["ERSM", "BTSM", "JC69", "HKY85"])
12-
SUITE["fitDiscrete"] = BenchmarkGroup(["ERSM", "BTSM", "JC69", "HKY85"])
12+
SUITE["fitdiscrete"] = BenchmarkGroup(["ERSM", "BTSM", "JC69", "HKY85"])
1313

1414
# Add benchmarks to nasm group
1515
SUITE["nasm"]["JC69"] = @benchmarkable JC69([0.5])
@@ -20,8 +20,8 @@ SUITE["nasm"]["HKY85"] = @benchmarkable P!(P(m1, 1.0), m1, 3.0)
2020
net_dat = readTopology("(((A:2.0,(B:1.0)#H1:0.1::0.9):1.5,(C:0.6,#H1:1.0::0.1):1.0):0.5,D:2.0);")
2121
species_alone = ["C","A","B","D"]
2222
dat_alone = DataFrame(trait=["hi","lo","lo","hi"])
23-
SUITE["fitDiscreteFixed"]["ERSM"] = @benchmarkable fitDiscrete(net_dat, :ERSM, species_alone, dat_alone; optimizeQ=false, optimizeRVAS=false)
24-
SUITE["fitDiscreteFixed"]["BTSM"] = @benchmarkable fitDiscrete(net_dat, :BTSM, species_alone, dat_alone; optimizeQ=false, optimizeRVAS=false)
23+
SUITE["fitDiscreteFixed"]["ERSM"] = @benchmarkable fitdiscrete(net_dat, :ERSM, species_alone, dat_alone; optimizeQ=false, optimizeRVAS=false)
24+
SUITE["fitDiscreteFixed"]["BTSM"] = @benchmarkable fitdiscrete(net_dat, :BTSM, species_alone, dat_alone; optimizeQ=false, optimizeRVAS=false)
2525

2626
fastafile = joinpath(@__DIR__, "..", "examples", "Ae_bicornis_Tr406_Contig10132.aln")
2727
dna_dat, dna_weights = readfastatodna(fastafile, true);
@@ -32,14 +32,14 @@ for edge in net_dna.edge #adds branch lengths
3232
setGamma!(edge, 0.5)
3333
end
3434
end
35-
SUITE["fitDiscreteFixed"]["JC69"] = @benchmarkable fitDiscrete(net_dna, :JC69, dna_dat, dna_weights; optimizeQ=false, optimizeRVAS=false)
36-
SUITE["fitDiscreteFixed"]["HKY85"] = @benchmarkable fitDiscrete(net_dna, :HKY85, dna_dat, dna_weights; optimizeQ=false, optimizeRVAS=false)
37-
38-
## fitDiscrete benchmarks
39-
SUITE["fitDiscrete"]["ERSM"] = @benchmarkable fitDiscrete(net_dat, :ERSM, species_alone, dat_alone; optimizeQ=true, optimizeRVAS=true)
40-
SUITE["fitDiscrete"]["BTSM"] = @benchmarkable fitDiscrete(net_dat, :BTSM, species_alone, dat_alone; optimizeQ=true, optimizeRVAS=true)
41-
SUITE["fitDiscrete"]["JC69"] = @benchmarkable fitDiscrete(net_dna, :JC69, dna_dat, dna_weights; optimizeQ=true, optimizeRVAS=true)
42-
SUITE["fitDiscrete"]["HKY85"] = @benchmarkable fitDiscrete(net_dna, :HKY85, dna_dat, dna_weights; optimizeQ=true, optimizeRVAS=true)
35+
SUITE["fitDiscreteFixed"]["JC69"] = @benchmarkable fitdiscrete(net_dna, :JC69, dna_dat, dna_weights; optimizeQ=false, optimizeRVAS=false)
36+
SUITE["fitDiscreteFixed"]["HKY85"] = @benchmarkable fitdiscrete(net_dna, :HKY85, dna_dat, dna_weights; optimizeQ=false, optimizeRVAS=false)
37+
38+
## fitdiscrete benchmarks
39+
SUITE["fitdiscrete"]["ERSM"] = @benchmarkable fitdiscrete(net_dat, :ERSM, species_alone, dat_alone; optimizeQ=true, optimizeRVAS=true)
40+
SUITE["fitdiscrete"]["BTSM"] = @benchmarkable fitdiscrete(net_dat, :BTSM, species_alone, dat_alone; optimizeQ=true, optimizeRVAS=true)
41+
SUITE["fitdiscrete"]["JC69"] = @benchmarkable fitdiscrete(net_dna, :JC69, dna_dat, dna_weights; optimizeQ=true, optimizeRVAS=true)
42+
SUITE["fitdiscrete"]["HKY85"] = @benchmarkable fitdiscrete(net_dna, :HKY85, dna_dat, dna_weights; optimizeQ=true, optimizeRVAS=true)
4343

4444
# If a cache of tuned parameters already exists, use it, otherwise, tune and cache
4545
# the benchmark parameters. Reusing cached parameters is faster and more reliable

docs/src/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Pages = [
4848
"man/multiplealleles.md",
4949
"man/trait_tree.md",
5050
"man/parsimony.md",
51-
"man/fitDiscrete.md"
51+
"man/fitdiscrete.md"
5252
]
5353
Depth = 3
5454
```

docs/src/lib/public.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ parsimonyGF
137137
Q
138138
randomTrait
139139
randomTrait!
140-
fitDiscrete
140+
fitdiscrete
141141
maxParsimonyNet
142142
nstates
143-
setrates!
144-
setalpha!
143+
stationary
144+
empiricalDNAfrequencies
145145
```
146146

147147
```@meta

docs/src/man/fitDiscrete.md

+112-107
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,142 @@
1+
```@setup traitevol_fixednet
2+
using PhyloNetworks
3+
using DataFrames
4+
mkpath("../assets/figures")
5+
```
6+
17
# Discrete Trait Evolution
28

39
With a phylogenetic network structure inferred, we can now estimate how quickly traits
4-
have evolved over time using a likelihood model. These traits should be discrete
5-
characteristics of a species such as feather color, diet type, or dna in aligned
6-
genetic sequences.
10+
have evolved over time using a likelihood model. These traits should be discrete
11+
characteristics of a species such as feather color, diet type,
12+
or DNA in aligned genetic sequences.
713

814
## Discrete Trait Data
915

10-
As with continuous trait evolution, we assume a fixed network, correctly rooted,
16+
As with continuous trait evolution, we assume a fixed network, correctly rooted,
1117
with branch lengths proportional to calendar time. We start with a network, then
1218
add data about the tips of this network. We allow data of two types.
13-
1. A vector of species names with a data frame of traits:
1419

15-
```@setup fitDiscrete
16-
using PhyloNetworks, DataFrames
17-
mkpath("../assets/figures")
18-
```
19-
20-
```@example fitDiscrete
21-
#read in network
22-
simple_net = readTopology("(A:3.0,(B:2.0,(C:1.0,D:1.0):1.0):1.0);");
23-
24-
#read in trait data
25-
simple_species = ["C","A","B","D"]
26-
simple_dat = DataFrame(trait=["hi","lo","lo","hi"])
27-
```
28-
29-
If your species names and trait data are in the same data frame, read in your data
30-
frame then subset the data like this:
31-
```@example fitDiscrete
32-
dat = DataFrame(species=["C","A","B","D"], trait=["hi","lo","lo","hi"])
33-
simple_species = dat[:species]
34-
simple_dat = DataFrame(trait = dat[:trait])
35-
```
36-
37-
2. To use dna data, read in the network structure then start with a fasta
38-
file. Reading the data from this file using the `readfastatodna` function. This
39-
creates a data frame of dna data and a vector of dna pattern weights.
40-
41-
```@example fitDiscrete
42-
#read in network
43-
dna_net = readTopology("((((((((((((((Ae_caudata_Tr275:1.0,Ae_caudata_Tr276:1.0):1.0,Ae_caudata_Tr139:1.0):1.0)#H1:1.0::0.6,((((((Ae_longissima_Tr241:1.0,Ae_longissima_Tr242:1.0):1.0,Ae_longissima_Tr355:1.0):1.0,(Ae_sharonensis_Tr265:1.0,Ae_sharonensis_Tr264:1.0):1.0):1.0,((Ae_bicornis_Tr408:1.0,Ae_bicornis_Tr407:1.0):1.0,Ae_bicornis_Tr406:1.0):1.0):1.0,((Ae_searsii_Tr164:1.0,Ae_searsii_Tr165:1.0):1.0,Ae_searsii_Tr161:1.0):1.0):1.0)#H2:1.0::0.6):1.0,(((Ae_umbellulata_Tr266:1.0,Ae_umbellulata_Tr257:1.0):1.0,Ae_umbellulata_Tr268:1.0):1.0,#H1:1.0::0.4):1.0):1.0,((Ae_comosa_Tr271:1.0,Ae_comosa_Tr272:1.0):1.0,(((Ae_uniaristata_Tr403:1.0,Ae_uniaristata_Tr357:1.0):1.0,Ae_uniaristata_Tr402:1.0):1.0,Ae_uniaristata_Tr404:1.0):1.0):1.0):1.0,(((Ae_tauschii_Tr352:1.0,Ae_tauschii_Tr351:1.0):1.0,(Ae_tauschii_Tr180:1.0,Ae_tauschii_Tr125:1.0):1.0):1.0,(#H2:1.0::0.4,((((Ae_mutica_Tr237:1.0,Ae_mutica_Tr329:1.0):1.0,Ae_mutica_Tr244:1.0):1.0,Ae_mutica_Tr332:1.0):1.0)#H4:1.0::0.6):1.0):1.0):1.0,(((T_boeoticum_TS8:1.0,(T_boeoticum_TS10:1.0,T_boeoticum_TS3:1.0):1.0):1.0,T_boeoticum_TS4:1.0):1.0,((T_urartu_Tr315:1.0,T_urartu_Tr232:1.0):1.0,(T_urartu_Tr317:1.0,T_urartu_Tr309:1.0):1.0):1.0):1.0):1.0,(((((Ae_speltoides_Tr320:1.0,Ae_speltoides_Tr323:1.0):1.0,Ae_speltoides_Tr223:1.0):1.0,Ae_speltoides_Tr251:1.0):1.0):1.0,#H4:1.0::0.4):1.0):1.0):1.0,Ta_caputMedusae_TB2:1.0):1.0,S_vavilovii_Tr279:1.0):1.0,Er_bonaepartis_TB1:1.0):1.0,H_vulgare_HVens23:1.0);");
20+
1. A vector of species names with a data frame of traits:
4421

45-
#read in dna data
46-
fastafile = joinpath(dirname(pathof(PhyloNetworks)), "..","examples",
47-
"Ae_bicornis_Tr406_Contig10132.aln")
48-
dna_dat, dna_weights = readfastatodna(fastafile, true);
49-
```
22+
```@example traitevol_fixednet
23+
# read in network
24+
net = readTopology("(A:3,((B:0.4)#H1:1.6::0.92,((C:0.4,#H1:0::0.08):0.6,D:1):1):1);");
25+
# read in trait data
26+
species = ["C","A","B","D"]
27+
dat = DataFrame(trait=["hi","lo","lo","hi"])
28+
```
29+
30+
If your species names and trait data are in the same data frame,
31+
read in your data frame then subset the data like this:
32+
```@example traitevol_fixednet
33+
dat = DataFrame(species=["C","A","B","D"], trait=["hi","lo","lo","hi"])
34+
species = dat[:species]
35+
dat = DataFrame(trait = dat[:trait])
36+
```
37+
38+
2. To use dna data, read in the network structure then start with a fasta
39+
file. Reading the data from this file using the `readfastatodna` function.
40+
This creates a data frame of dna data and a vector of dna pattern weights.
41+
42+
```@example traitevol_fixednet
43+
# read in network
44+
dna_net = readTopology("((((((((((((((Ae_caudata_Tr275:1.0,Ae_caudata_Tr276:1.0):1.0,Ae_caudata_Tr139:1.0):1.0)#H1:1.0::0.6,((((((Ae_longissima_Tr241:1.0,Ae_longissima_Tr242:1.0):1.0,Ae_longissima_Tr355:1.0):1.0,(Ae_sharonensis_Tr265:1.0,Ae_sharonensis_Tr264:1.0):1.0):1.0,((Ae_bicornis_Tr408:1.0,Ae_bicornis_Tr407:1.0):1.0,Ae_bicornis_Tr406:1.0):1.0):1.0,((Ae_searsii_Tr164:1.0,Ae_searsii_Tr165:1.0):1.0,Ae_searsii_Tr161:1.0):1.0):1.0)#H2:1.0::0.6):1.0,(((Ae_umbellulata_Tr266:1.0,Ae_umbellulata_Tr257:1.0):1.0,Ae_umbellulata_Tr268:1.0):1.0,#H1:1.0::0.4):1.0):1.0,((Ae_comosa_Tr271:1.0,Ae_comosa_Tr272:1.0):1.0,(((Ae_uniaristata_Tr403:1.0,Ae_uniaristata_Tr357:1.0):1.0,Ae_uniaristata_Tr402:1.0):1.0,Ae_uniaristata_Tr404:1.0):1.0):1.0):1.0,(((Ae_tauschii_Tr352:1.0,Ae_tauschii_Tr351:1.0):1.0,(Ae_tauschii_Tr180:1.0,Ae_tauschii_Tr125:1.0):1.0):1.0,(#H2:1.0::0.4,((((Ae_mutica_Tr237:1.0,Ae_mutica_Tr329:1.0):1.0,Ae_mutica_Tr244:1.0):1.0,Ae_mutica_Tr332:1.0):1.0)#H4:1.0::0.6):1.0):1.0):1.0,(((T_boeoticum_TS8:1.0,(T_boeoticum_TS10:1.0,T_boeoticum_TS3:1.0):1.0):1.0,T_boeoticum_TS4:1.0):1.0,((T_urartu_Tr315:1.0,T_urartu_Tr232:1.0):1.0,(T_urartu_Tr317:1.0,T_urartu_Tr309:1.0):1.0):1.0):1.0):1.0,(((((Ae_speltoides_Tr320:1.0,Ae_speltoides_Tr323:1.0):1.0,Ae_speltoides_Tr223:1.0):1.0,Ae_speltoides_Tr251:1.0):1.0):1.0,#H4:1.0::0.4):1.0):1.0):1.0,Ta_caputMedusae_TB2:1.0):1.0,S_vavilovii_Tr279:1.0):1.0,Er_bonaepartis_TB1:1.0):1.0,H_vulgare_HVens23:1.0);");
45+
# read in dna data
46+
fastafile = joinpath(dirname(pathof(PhyloNetworks)), "..","examples","Ae_bicornis_Tr406_Contig10132.aln")
47+
dna_dat, dna_weights = readfastatodna(fastafile, true);
48+
dna_dat
49+
dna_weights
50+
```
5051

5152
## Choosing a Substitution Model
5253

53-
After reading in your data, choose a model to describe how evolutionary changes
54-
(or substitutions, in the case of DNA) happened over time. We offer a selection
55-
of Markov substitution models to describe the evolutionary process.
54+
After reading in your data, choose a model to describe how evolutionary changes
55+
(or substitutions, in the case of DNA) happened over time.
56+
Available Markov substitution models are described below.
5657

57-
### Generic Trait Models
58+
### Generic Trait Models
5859

5960
These models works well for any type of trait we may want to model. For general
60-
trait types, use one of these three models:
61-
`:ERSM` Equal Rates Substitution Model
62-
`:BTSM` Binary Trait Substitution Model
63-
`:TBTSM` Two Binary Trait Substituion Model
64-
65-
### DNA-Specific Models
66-
67-
The DNA-specific models are optimized for aligned sequence data. We offer JC69
68-
and HKY85 models in both relative and absolute versions. The JC69 model was
69-
developed by Jukes and Cantor in 1969 and uses one rate for all type of substitutions.
70-
The HKY85 model was developed in 1985 by Hasegawa, Kishino, & Yano. It treats
71-
transitions differently from transversions.
72-
`:JC69` Jukes Cantor 69 Model
73-
`:HKY85` Hasegawa, Kishino and Yano 1985
74-
75-
## Running FitDiscrete
76-
77-
To infer evolutionary rates, run the `fitDiscrete` function on the network and data.
78-
It will calculate the maximum likelihood score of a network given one or more
79-
discrete trait characters at the tips. Along each edge, evolutionary changes
80-
are modeled with a continous time Markov model, with parameters estimated by
81-
maximizing the likelihood. At each hybrid node, the trait is assumed to be
82-
inherited from the immediate parent (or parents, in the case of a hybrid edge).
83-
If there is a hybrid edge, the trait is modeled according to the parents' weighted
84-
average genetic contributions, as measured by inheritance gamma γ. The model
85-
currently ignores incomplete lineage sorting.
61+
trait types, use one of these three models:
62+
- `:BTSM` Binary Trait Substitution Model (2 states, rates unconstrained)
63+
- `:ERSM` Equal Rates Substitution Model
64+
(`k` states, all transitions possible with equal rates)
65+
- `:TBTSM` Two Binary Trait Substituion Model (though not fully implemented yet)
66+
67+
### DNA-Specific Models
68+
69+
The DNA-specific models are optimized for aligned sequence data.
70+
The 4 nucleotide states are from
71+
[BioSymbols](https://github.com/BioJulia/BioSymbols.jl)
72+
(listed [here](http://biojulia.net/BioSymbols.jl/stable/nucleicacids/)).
73+
Each model has a relative and an absolute version.
74+
- `:JC69` Jukes & Cantor 1969 model: one single rate for all transitions.
75+
The relative version has values -1 along the diagonal of the rate matrix
76+
(1 expected transition / unit of time). The absolute version has an extra
77+
parameter to scale the rate matrix.
78+
- `:HKY85` Hasegawa, Kishino & Yano 1985: treats transitions differently
79+
from transversions.
80+
81+
## Fitting the model
82+
83+
To infer evolutionary rates, run the `fitdiscrete` function on the network and data.
84+
It will calculate the maximum likelihood score of a fixed network
85+
given one or more discrete trait characters at the tips.
86+
Along each edge, evolutionary changes
87+
are modeled with a continous time Markov model, with parameters estimated by
88+
maximizing the likelihood. At each hybrid node, the trait is assumed to be
89+
inherited from the immediate parent (or parents, in the case of a hybrid node).
90+
At a hybrid node, the trait is assumed to be inherited from one or the other
91+
parent, with probabilities equal to the inheritance γ of each parent edge
92+
(which is given by the network).
93+
The model ignores incomplete lineage sorting (e.g. hemiplasy).
8694

8795
### General Trait Data
8896

89-
```@example fitDiscrete
90-
s1 = fitDiscrete(simple_net, :ERSM, simple_species, simple_dat; optimizeQ=false,
91-
optimizeRVAS=false)
92-
s2 = fitDiscrete(simple_net, :BTSM, simple_species, simple_dat; optimizeQ=false,
93-
optimizeRVAS=false)
97+
```@repl traitevol_fixednet
98+
s1 = fitdiscrete(net, :ERSM, species, dat; optimizeQ=false)
99+
s2 = fitdiscrete(net, :BTSM, species, dat; optimizeQ=false)
94100
```
95-
In this `fitDiscrete` call, we do not optimize rates or allow for rate variation
96-
across sites.
97-
98-
If `optimizeQ = true`, the `fitDiscrete` function estimates the evolutionary rate
99-
or rates. Because we didn't allow for rate variation across sites in these models,
100-
we do not optimize the way rates may vary across trait types.
101-
102-
```@example fitDiscrete
103-
s3 = fitDiscrete(simple_net, :ERSM, simple_species, simple_dat; optimizeQ=true,
104-
optimizeRVAS=true)
105-
s4 = fitDiscrete(simple_net, :BTSM, simple_species, simple_dat; optimizeQ=true,
106-
optimizeRVAS=true)
101+
In this `fitdiscrete` call, we do not optimize rates or allow for rate variation
102+
across sites. The default rates (which act as starting value if rates
103+
were to be optimized) are chosen equal to the inverse of the total edge lengths
104+
in the network (or 1/ntax if all branch lengths are missing).
105+
106+
If `optimizeQ = true` (which is the default), the `fitdiscrete`
107+
function estimates the parameters of the rate matrix.
108+
Because we didn't allow for rate variation across sites in these models,
109+
there is nothing to optimize in the way rates may vary across traits (sites).
110+
111+
```@repl traitevol_fixednet
112+
s3 = fitdiscrete(net, :ERSM, species, dat)
113+
s4 = fitdiscrete(net, :BTSM, species, dat)
107114
```
108115

109116
### DNA Data
110117

111-
For DNA data, use `:JC69` or `:HKY85` models.
112-
```@example fitDiscrete
113-
d1 = fitDiscrete(dna_net, :JC69, dna_dat, dna_weights, :RV; optimizeQ=false,
114-
optimizeRVAS=false)
115-
d2 = fitDiscrete(dna_net, :HKY85, dna_dat, dna_weights, :RV; optimizeQ=false,
116-
optimizeRVAS=false)
118+
For DNA data, use one of `:JC69` or `:HKY85`.
119+
To allow for rate variation across sites, use the `:RV` option.
120+
121+
```@example traitevol_fixednet
122+
d1 = fitdiscrete(dna_net, :JC69, dna_dat, dna_weights, :RV; optimizeQ=false, optimizeRVAS=false)
123+
d2 = fitdiscrete(dna_net, :HKY85, dna_dat, dna_weights, :RV; optimizeQ=false, optimizeRVAS=false)
117124
```
118-
In these `fitDiscrete` models, we do not optimize rates (`optimizeQ=false`), but
119-
we do allow for rate variation across sites.
125+
In these `fitdiscrete` models, we do not optimize rates (`optimizeQ=false`), but
126+
we do allow for rate variation across sites, with a default α of 1.
120127

121128
### Rate Variation Across Sites
122129

123-
In its default version, `fitDiscrete` does not allow for rate variation across sites.
124-
To allow for rate variation across sites in your estimate of evolutionary rates
125-
(or rate variation across trait types, in the case of general trait types),
126-
include `:RV`. If you include `:RV` and `optimizeRVAS = true`, the model will
127-
not only allow for rate variation, but it will also optimize how rates vary across
128-
sites.
130+
In its default version, `fitdiscrete` does not allow for rate variation across sites.
131+
To allow for rate variation across sites in your estimate of evolutionary rates
132+
(or rate variation across traits in the case of general traits),
133+
include `:RV`. If you include `:RV` and `optimizeRVAS = true`,
134+
the model will allow for rate variation and
135+
also optimize the parameter α of the distribution of rates across sites.
129136

130137
We optimize the evolutionary rates and the way rates vary across sites for the
131-
DNA data here:
132-
```@example fitDiscrete
133-
d3 = fitDiscrete(dna_net, :JC69, dna_dat, dna_weights, :RV; optimizeQ=true,
134-
optimizeRVAS=false)
135-
d4 = fitDiscrete(dna_net, :HKY85, dna_dat, dna_weights, :RV; optimizeQ=true,
136-
optimizeRVAS=false)
137-
```
138+
DNA data here:
139+
```@repl traitevol_fixednet
140+
d3 = fitdiscrete(dna_net, :JC69, dna_dat, dna_weights, :RV; optimizeRVAS=false)
141+
d4 = fitdiscrete(dna_net, :HKY85, dna_dat, dna_weights, :RV)
142+
```

0 commit comments

Comments
 (0)