In case of the joint analysis of total and nascent RNA data, for each transcript with at least one intron, the exonic and intronic quantifications are available in the Total and in the Nascent RNA libraries. The system of equations (1) describes the dynamics of the total RNA population, but when integrated between zero and the time of labeling (\(t_L\)) it can be used to describe nascent RNA. For matter of simplicity INSPEcT assumes that, during the labeling time, synthesis and processing rates are constant and nascent transcripts are not degraded. The set of equations to describe Total and Nascent RNA is:
\[\begin{equation} \left\{ \begin{array}{l l} \dot{P}_{R}=k_1 - k_2 \, \cdot \, P_{R} \\ \dot{T}_{R}=k_1 - k_3 \, \cdot \, (T_{R} - P_{R}) \\ s_F \, \cdot \, P_{L}=\frac{k_1}{k_2} - ( 1 - e^{k_2 \, \cdot \, t_L} ) \\ s_F \, \cdot \, T_{L}=k_1 \, \cdot \, t_L \end{array} \right. \tag{2} \end{equation}\]
where \(P_{R}\) and \(T_{R}\) are the premature and total RNA levels, respectively, estimated from the total RNA library, \(P_{L}\) and \(T_{L}\) are premature and total RNA levels, respectively, estimated from the nascent RNA library at each condition or time-point. First of all, \(\dot{P}_{R}\) and \(\dot{T}_{R}\) are estimated from the interpolation of \(P_R(t)\) and \(T_R(t)\) via cubic splines. INSPEcT exploits the overdetermination of the system (three unknowns: \(k_1\), \(k_2\) and \(k_3\); and four equations) to calculate a scaling factor (\(s_F\)) between the Total and Nascent RNA for each condition or time-point (De Pretis et al. 2015).
First guess estimation of the ratesThe rates of synthesis, processing and degradation are calculated from the Total and Nascent RNA quantifications by the newINSPEcT function:
tpts<-c(0,1/6,1/3,1/2,1,1.5,2,4,8,12,16)
tL<-1/6
nascentInspObj<-newINSPEcT(tpts=tpts
,labeling_time=tL
,nascentExpressions=nasExp_DESeq2
,matureExpressions=matExp_DESeq2)
During this step, INSPEcT calculates a scaling factor between each time-point of Total and Nascent expressions (as described in the section above) and integrates the differential equations (2) assuming that, between experimental observations, total RNA, premature RNA and synthesis rate, behave linearly (linear piecewise), and that processing and degradation rates are constant (constant piecewise). Rates estimated by this procedure can be accessed from the INSPEcT object by the method ratesFirstGuess, which allows to access also RNA concentrations and variances associated to the experimental observations:
round(ratesFirstGuess(nascentInspObj,'total')[1:5,1:3],3)
## total_0 total_0.166666667 total_0.333333333
## 100503670 605.805 609.366 601.865
## 101206 5.107 5.356 5.196
## 101489 15.629 15.767 15.606
## 102436 1.543 1.107 1.305
## 104458 86.966 93.632 88.837
round(ratesFirstGuessVar(nascentInspObj,'total')[1:5,1:3],3)
## total_0 total_0.166666667 total_0.333333333
## 100503670 775.569 784.570 764.586
## 101206 0.382 0.417 0.392
## 101489 1.192 1.208 1.179
## 102436 0.281 0.145 0.202
## 104458 24.917 28.736 25.866
round(ratesFirstGuess(nascentInspObj,'synthesis')[1:5,1:3],3)
## synthesis_0 synthesis_0.166666667 synthesis_0.333333333
## 100503670 231.119 211.859 210.099
## 101206 4.875 4.412 3.964
## 101489 7.749 7.412 7.421
## 102436 32.087 28.312 28.645
## 104458 47.333 46.424 50.867
The INSPEcT object can be subset to focus on a specific set of genes, and for the sake of speeding up the downstream analysis, we will focus on the first 10 genes of the INSPEcT object.
nascentInspObj10<-nascentInspObj[1:10]
The complete pattern of total and pre-mRNA concentrations variation together with the synthesis, degradation and processing rates can be visualized using the inHeatmap method (Figure 1):
inHeatmap(nascentInspObj10, clustering=FALSE)
Figure 1: inHeatmap of the ratesFirstGuess
Heatmap representing the concentrations of total RNA, of premature RNA and the first guess of the rates of the RNA life cycle
In case of a long \(t_L\) (more than 30 minutes), it can be useful to set the argument degDuringPulse equal to TRUE to estimate the rates of the RNA life-cycle without assuming that nascent transcripts are not degraded during the labeling time. The longer the labelling time is the weaker this assumption gets, however, taking into account nascent RNA degradation involves the solution of a more complicated system of equations and can originate unrealistic high rates of synthesis, processing and degradation.
nascentInspObjDDP<-newINSPEcT(tpts=tpts
,labeling_time=tL
,nascentExpressions=nasExp_DESeq2
,matureExpressions=matExp_DESeq2
,degDuringPulse=TRUE)
For short labeling times, as 10 minutes can be considered, the absence of degradation during the pulse is a good assumption and similar rates are estimated in both cases. In Figure 2 we compared the degradation rates estimated with or without the assumption that degradation of mature RNA occurs during the labeling time.
k3 <- ratesFirstGuess(nascentInspObj, 'degradation')
k3ddp <- ratesFirstGuess(nascentInspObjDDP, 'degradation')
plot(rowMeans(k3), rowMeans(k3ddp), log='xy',
xlim=c(.2,10), ylim=c(.2,10),
xlab='no degradation during pulse',
ylab='degradation during pulse',
main='first guess degradation rates')
abline(0,1,col='red')
Figure 2: Dotplot of degradation rates calculated with or without the assumption of no degradation during pulse
First guess of the degradation rates was calculated with or without degDuringPulse option. In red is represented the line of equation y = x.
The rates evaluated during the âfirst guessâ are highly exposed to the experimental noise. In particular, processing and degradation rates sum up the noise coming from different experimental data (i.e. the Total and the Nascent libraries), and could be challenging to distinguish real variations from noise. For this reason, the method modelRates fits either sigmoid or impulse functions to total RNA, processing and degradation rates, that minimize the error on experimental data. In this approach, premature RNA and synthesis rate functional forms directly result from the system of equations (1).
nascentInspObj10<-modelRates(nascentInspObj10, seed=1)
The rates computed through this modeling procedure are accessible via the method viewModelRates and can visualized via the method inHeatmap, setting the argument type=âmodelâ} (Figure 3).
round(viewModelRates(nascentInspObj10, 'synthesis')[1:5,1:3],3)
## synthesis_0 synthesis_0.17 synthesis_0.33
## 100503670 208.688 208.688 208.688
## 101206 4.640 4.466 4.242
## 101489 7.524 7.454 7.348
## 102436 25.632 25.663 25.712
## 104458 47.738 47.738 47.738
inHeatmap(nascentInspObj10, type='model', clustering=FALSE)
Figure 3: inHeatmap of the rates after the second step of modeling
Heatmap representing the concentrations of total RNA, of premature RNA and the rates of the RNA life cycle after the second step of modeling.
For each rate and time point, 95% confidence intervals are calculated and used to test the variability of a rate. Specifically, a chi-squared goodness-of-fit test is performed to assess how a constant rate fit within confidence intervals. Confidence intervals can be accessed by the method viewConfidenceIntervals, the p-values of the rates variability tests can be accessed by the method ratePvals and the regulatory class assigned to each gene by the method geneClass. In particular, each gene is assigned to a class named after the set of varying rates: âno-regâ denotes a gene whose rates are constant over time, âsâ denotes a gene whose synthesis changes over time, âpâ denotes a gene whose processing changes over time, âdâ denotes a gene whose degradation changes over time. Genes regualted by a more than one rate have a class composed by more letters, for example, the class âspâ represnents genes regulated at the level of both synthesis and processing rates.
head(ratePvals(nascentInspObj10),3)
## synthesis processing degradation
## 100503670 8.663546e-01 1 0.9999919
## 101206 7.002705e-08 1 0.9999919
## 101489 1.612946e-03 1 0.0142093
head(geneClass(nascentInspObj10),3)
## 100503670 101206 101489
## "no-reg" "s" "sd"
The method plotGene can be used to fully investigate the profiles of RNA concentrations and rates of a single gene. Estimated synthesis, degradation and processing rates, premature RNA and total RNA concentrations are displayed with solid thin lines, while their standard deviations or confidence intervals are in dashed lines and the modelled rates and concentrations are in thick solid lines. This example shows a gene of class âaâ, indicating that its expression levels are controlled just by synthesis rate (Figure 4).
plotGene(nascentInspObj10, ix="101206")
Figure 4: Plot of a single gene resolved using nascent and total RNA
Plot of concentrations and rates over time for the given gene 101206. Total and nascent RNA were used to resolve the whole set of rates and concentrations.
The global quality of each model is evaluated through chi-squared goodness-of-fit test, where the number of degrees of freedom equals the difference between the experimental observations and the number of parameters used for the modelling. The results of this test can be accessed via the method chisqmodel. Here we visualized them as a histogram (Figure 5) and eventually used to discard badly fitted genes.
chisq<-chisqmodel(nascentInspObj10)
hist(log10(chisq), main='', xlab='log10 chi-squared p-value')
Figure 5: Histogram of the p-values from the goodness of fit test for modeled genes
discard<-which(chisq>1e-2)
featureNames(nascentInspObj10)[discard]
## [1] "104458" "105148" "105348" "107435"
nascentInspObj_reduced<-nascentInspObj10[-discard]
Selection of the regulative scenario without assumptions on the functional form
In case the sigmoid or impulse functional forms are not suited to describe the experimental data, such as for oscillatory genes, the method modelRatesNF can be used to assess the regulatory scenario. This method estimates confidence intervals on the synthesis, processing and degradation rates calculated in the first step of the analysis, i.e. without assuming any specific functional form.
nascentInspObj10NF<-nascentInspObj[1:10]
nascentInspObj10NF<-modelRatesNF(nascentInspObj10NF)
Rates estimates with their confidence intervals are then used to assess the regulatory scenarios, like described in for the models where the functional form is fixed.
head(ratePvals(nascentInspObj10NF),3)
## synthesis processing degradation
## 100503670 3.442920e-03 0.9989537 0.3060441
## 101206 2.746373e-07 0.9989537 0.9999485
## 101489 6.860230e-05 0.9989537 0.8886645
head(geneClass(nascentInspObj10NF),3)
## 100503670 101206 101489
## "s" "s" "s"
Also the method plotGene can be used:
plotGene(nascentInspObj10NF, ix="101206")
Figure 6: Plot of a single gene resolved using nascent and total RNA
Plot of concentrations and rates over time for the given gene 101206. No assumptions on the functional form of the rate was done in this case to calculate confidence intervals.
Without assumptions on the functional form, the quality of each model in describing the data cannot be calculated because the model used has no residual degrees of freedom over the experimental data and no test statistic can apply.
Analysis of Total RNA without Nascent (INSPEcT-)The absence of the nascent RNA component makes the identification of a unique solution of the system more difficult. Nonetheless, the joint analysis of premature and mature RNA time-course RNA-seq analysis is an important source of information in regards of RNA dynamics. The main idea behind this relies in the fact that genes that are modulated transcriptionally (i.e. by the synthesis rate) respond in their RNA levels following a precise pattern, that is premature RNA and mature RNA are modulated to the same extent (same fold change compared to unperturbed condition) but with different timing. In fact, the mature RNA follows the modulation of the premature RNA by a delay that is indicative to the mature RNA stability (i.e. degradation rate). Deviations from this behavior are signs of post-transcriptional regulation. We developed a computational approach that exploits these concepts and is able to quantify RNA dynamics based on time-course profiling of total RNA-seq data with good approximation. Without nascent RNA, the sole information of total (\(T\), exonic quantification) and premature (\(P\), intronic quantification) from the Total library is available and used to model the RNA dynamics. In particular, we model premature RNA (\(P\)) and mature RNA (\(M=T-P\)), using the equation:
\[\begin{equation} \begin{array}{l l} \dot{M}=k_2 \, P(t) - k_3 \, M(t) \end{array} \tag{3} \end{equation}\]
We start solving the equations assuming constant processing and degradation rates over the time-course and interpolating \(P\) with a linear piecewise in order to find the \(k2\) and \(k3\) that minimize the error over \(M(t)\), while \(k1(t)\) is obtained as follows:
\[\begin{equation} \begin{array}{l l} k_1(t) = \dot{P(t)} + k_2 \, P(t) \\ \end{array} \tag{4} \end{equation}\]
After that, \(k_1(t)\) is used in combination with \(P(t)\) and \(T(t)\) to obtain \(k_2(t)\) and \(k_3(t)\) using the same procedure implemented for the first guess estimation of the rates in the analysis of nascent and total RNA.
First guess estimation of the ratesThe procedure described above is implemented in the method newINSPEcT, which creates the INSPEcT object for the analysis and gives a first estimation of the synthesis, processing and degradation rates along the time-course, for those genes with enough signal for both introns and exons. In comparison to the mature and nascent configuration, from the practical point of view, nothing changes except for the absence of \(t_L\) and new synthesized expression data.
matureInspObj<-newINSPEcT(tpts=tpts
,labeling_time=NULL
,nascentExpressions=NULL
,matureExpressions=matExp_DESeq2)
All the methods that apply to the INSPEcT object created with the nascent RNA apply also to the object created with the sole total RNA. For example, we can compare the time-averaged rates of synthesis estimated in this first step of modeling with or without the nascent RNA, by extracting them with the ratesFirstGuess (Figure 7).
cg <- intersect(featureNames(nascentInspObj),
featureNames(matureInspObj))
k1Nascent <- ratesFirstGuess(nascentInspObj[cg,], 'synthesis')
k1Mature <- ratesFirstGuess(matureInspObj[cg,], 'synthesis')
smoothScatter(log10(rowMeans(k1Nascent)),
log10(rowMeans(k1Mature)),
main='synthesis rates',
xlab='nascent + mature RNA',
ylab='mature RNA')
abline(0,1,col='red')
Figure 7: Dotplot of synthesis rates calculated with or without nascent RNA
First guess of the synthesis rates calculated on the same set of genes with or without the nascent RNA information. In red is represented the line of equation y = x.
Similarly to the procedure with the nascent RNA, INSPEcT provides an additional step of modeling, where the software assigns to the rates of the RNA cycle a sigmoid or impulse form to describe their behavior over time (see the corresponding section in âAnalysis of Total and Nascent RNAâ). During this procedure 8 independent models for each gene are tested (all the combinations of constant/non-constant functions for each of the three rates), and the best model is chosen based on the trade-off between the goodness of fit and the simplicity. This modeling procedure refines the estimation of the rates and gives a statistical confidence about the variation of each rate during the time-course.
matureInspObj10 <- matureInspObj[1:10, ]
matureInspObj10 <- modelRates(matureInspObj10, seed=1)
In figure 8, the same gene represented in figure 4 is plotted. Also in this case, estimated synthesis, degradation and processing rates, premature RNA and total RNA concentrations are displayed with solid thin lines, while their standard deviations are in dashed lines and the modelled rates and concentrations are in thick solid lines.
plotGene(matureInspObj10, ix="101206")
## Confidence intervals.
Figure 8: Plot of a single gene resolved using only total RNA
Plot of concentrations and rates over time for the given gene 101206. Only total RNA was used to resolve the whole set of rates and concentrations.
Analogously to INSPEcT+, also without the Nascent RNA information confidence intervals for each rate and time point are estimated (viewConfidenceIntervals method) and the quality of the models are calculated (chisqmodel method).
Selection of the regulative scenario without assumptions on the functional formAlso in the case of Total RNA analysis, when sigmoid or impulse functional forms are not suited to describe the experimental data the method modelRatesNF should be used to assess the regulatory scenario by the estimation of the confidence intervals on the synthesis, processing and degradation rates calculated in the first step of the analysis, i.e. without assuming any specific functional form.
matureInspObj10NF<-modelRatesNF(matureInspObj[1:10])
Rates estimates with their confidence intervals are then used to assess the regulatory scenarios, like described in for the models where the functional form is fixed.
Performance evaluation with simulated dataINSPEcT offers functionalities to build a synthetic dataset that can be used to evaluate the performance of the tool in classifying rates as constant or variable over time, to configure the model selection parameters, and to predict the number of time points and replicates necessary to achieve a given classification performance.
Generate simulated data with sigmoid and impulsive ratesThe method makeSimModel samples from an INSPEcT object the absolute values of the rates, their fold changes compared to time zero, the correlations between rates and fold-changes and the variance associated to experimental observations. These distributions estimated from real data are then used to simulate a given number of genes (set with nGenes parameter) with specified probability to have each rate as a constant, sigmoid or impulse function; by default these values are 50% constant, 20% sigmoid and 30% impulse.
simRates<-makeSimModel(nascentInspObj, 1000, seed=1)
# table(geneClass(simRates))
makeSimModel produces an object of class INSPEcT_model, to be analyzed it must be transformed in an INSPEcT object using the makeSimDataset method. It takes as arguments the number of replicates required and the time points at which the data should be virtually collected. Regarding the latter point, the new time-course must be designed as a sampling of the original experimental time window (same initial and final conditions). The object created by this method can be modelled via modelRates as any other object of class INSPEcT, and in this case the results could be compared with the ground truth and the performance of the procedure with given number of replicates and time points can be estimated. In order to avoid long computation time, the next two chunks of code have been previously evaluated and will be not computed within this vignette.
newTpts <- c(0.00, 0.13, 0.35, 0.69, 1.26, 2.16, 3.63,
5.99, 9.82, 16.00)
nascentSim2replicates<-makeSimDataset(object=simRates
,tpts=newTpts
,nRep=2
,NoNascent=FALSE
,seed=1)
nascentSim2replicates<-modelRates(nascentSim2replicates[1:100]
,seed=1)
newTpts <- c(0.00, 0.10, 0.26, 0.49, 0.82, 1.32, 2.06,
3.16, 4.78, 7.18, 10.73, 16.00)
nascentSim3replicates<-makeSimDataset(object=simRates
,tpts=newTpts
,nRep=3
,NoNascent=FALSE
,seed=1)
nascentSim3replicates<-modelRates(nascentSim3replicates[1:100]
,seed=1)
Starting from the very same simRates, it is also possible to generate INSPEcT objects without information about the nascent RNA (argument NoNascent set to TRUE). However, it is not allowed to produce artificial gene sets starting from INSPEcT object without nascent RNA because the experimental estimation of the synthesis rate is mandatory to guarantee the good quality of the simulated data.
newTpts <- c(0.00, 0.13, 0.35, 0.69, 1.26, 2.16, 3.63,
5.99, 9.82, 16.00)
matureSim2replicates<-makeSimDataset(object=simRates
,tpts=newTpts
,nRep=2
,NoNascent=TRUE
,seed=1)
modelSelection(matureSim2replicates)$thresholds$chisquare <- 1
matureSim2replicates<-modelRates(matureSim2replicates[1:100]
,seed=1)
newTpts <- c(0.00, 0.10, 0.26, 0.49, 0.82, 1.32, 2.06,
3.16, 4.78, 7.18, 10.73, 16.00)
matureSim3replicates<-makeSimDataset(object=simRates
,tpts=newTpts
,nRep=3
,NoNascent=TRUE
,seed=1)
modelSelection(matureSim3replicates)$thresholds$chisquare <- 1
matureSim3replicates<-modelRates(matureSim3replicates[1:100]
,seed=1)
Once the simulated data have been produced and analysed, it is possible to compare the results obtained by the method modelRates and the object simRates, which contains the ground truth of rates.
The method rocCurve, for example, measures the performace of the constant/variable classification individually for the rates of synthesis, processing and degradation, using the receiver operating characteristic (ROC) curve (Figure 9).
data("nascentSim2replicates","nascentSim3replicates",
"matureSim2replicates","matureSim3replicates",package='INSPEcT')
par(mfrow=c(2,2))
rocCurve(simRates,nascentSim2replicates)
title("2rep. 10t.p. Total and nascent RNA", line=3)
rocCurve(simRates,nascentSim3replicates)
title("3rep. 12t.p. Total and nascent RNA", line=3)
rocCurve(simRates,matureSim2replicates)
title("2rep. 10t.p. Total RNA", line=3)
rocCurve(simRates,matureSim3replicates)
title("3rep. 12t.p. Total RNA", line=3)
Figure 9: ROC analysis of INSPEcT classification
For each rate, INSPEcT classification performance is measured in terms of sensitivity, TP / (TP + FN), and specificity, TN / (TN + FP), using a ROC curve analysis; false negatives (FN) represent cases where the rate is identified as constant while it was simulated as varying; false positives (FP) represent cases where INSPEcT identified a rate as varying while it was simulated as constant; on the contrary, true positives (TP) and negatives (TN) are cases of correct classification of varying and constant rates, respectively; sensitivity and specificity are computed using increasing thresholds for the Brown method used to combine multiple p-values derived from the log-likelihood ratio tests
Further, the method rocThresholds can be used to assess the sensitivity and specificity that is achieved with different thresholds of the chi-squared and Brown tests (Figure 10) and returns the thresholds that maximize both sensitivity and specificity.
rocThresholds(simRates[1:100],nascentSim2replicates)
Figure 10: Effect of chi-squared and Brown tests thresholds in INSPEcT classification
Plot of the sensitivity (black curve) and specificity (red curve) that is achieved after performing the log-likelihood ratio and Brown method for combining p-values with selected thresholds; thresholds that can be set for chi-squared test to accept models that will undergo the log-likelihood ratio test and for Brown p-value to assess variability of rates
## synthesis processing degradation
## 0.005865058 0.894320721 0.571718439
Generate simulated data with oscillatory rates
INSPEcT also offers the possibility to generate a dataset with oscillatory rates. In this case, the method makeOscillatorySimModel can generate two types of simulated datasets: one where 50% of the genes have oscillatory synthesis rates (while processing and degradation are always constant), and one where 50% of the genes have both synthesis and degradation oscillatory rates (and processing always constant). In the latter case, the oscillation phase of synthesis and degradation can be coordinated. To resemble circadian rhythms, the oscillation frequencies is about 24 hours, while oscillation intensities are randomly sampled.
oscillatorySimRates<-makeOscillatorySimModel(nascentInspObj, 1000
, oscillatoryk3=FALSE, seed=1)
oscillatorySimRatesK3<-makeOscillatorySimModel(nascentInspObj, 1000
, oscillatoryk3=TRUE, k3delay=4, seed=1)
As in the previous case, after generating the rates pattern, a simulated dataset has to be created with the method makeSimDataset, where the number of replicates and the time-points of the experimental observations are set.
newTpts <- seq(0,48,length.out=13)
oscillatoryWithNascent<-makeSimDataset(object=oscillatorySimRates
,tpts=newTpts
,nRep=3
,NoNascent=FALSE
,seed=1)
oscillatoryWithNascentK3<-makeSimDataset(object=oscillatorySimRatesK3
,tpts=newTpts
,nRep=3
,NoNascent=FALSE
,seed=1)
Non default parameters for modeling and model selection
If desired, different parameters can be set for both the modelling and the testing part. Regarding the modeling part, we might want to increase the number of different initializations that are performed for each gene (nInit option) or increase the maximum number of steps in the rates optimization process (nIter option). All these choices could improve the performance of the method, but also the needed computational time; the impact of these options on the quality of the modelling can be evaluated using simulated datasets.
nascentInspObj10<-modelRates(nascentInspObj10, nInit=20, nIter=1000)
Alternatively, it is possible to change the thresholds for goodness-of-fit (chi-squared) and variability tests. The goodness-of-fit is used to discard bad models that will not enter in the model selection. By default, the threshold of acceptance is set to 0.1 and in this example we decide to be less stringent and set the threshold to 0.2. In case of low number of time points, few or no models can result in a low chi-square. In these cases, it could be necessary to use larger values for the chi-squared test threshold, or be completely comprehensive and set the threshold to 1. The threshold relative to the variability test is used to call differential regulation and can be set independently for each rate. Low thresholds reflect in a stricter call for differential regulation of the rate. In this example, we are changing the thresholds of both the goodness-of-fit and variability tests, eventually regenerating p-values and modeled rates.
matureInspObj10 <- calculateRatePvals(matureInspObj10, p_goodness_of_fit = .2, p_variability = c(.01,.01,.05))
In general, to increase reproducibility of the results, the parameters used for the modeling and for the model selection can be accessed also later by using the method modelingParams and modelSelection:
## modeling
str(modelingParams(matureInspObj10))
## List of 7
## $ estimateRatesWith: chr "der"
## $ useSigmoidFun : logi TRUE
## $ nInit : num 10
## $ nIter : num 300
## $ Dmin : num 1e-06
## $ Dmax : num 10
## $ seed : num 1
## model selection and testing framework
str(modelSelection(matureInspObj10))
## List of 6
## $ modelSelection : chr "aic"
## $ preferPValue : logi TRUE
## $ padj : logi TRUE
## $ p_goodness_of_fit : num 0.2
## $ p_variability : num [1:3] 0.01 0.01 0.05
## $ limitModelComplexity: logi FALSE
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4