├── .Rbuildignore ├── .Rhistory ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── R ├── .Rhistory ├── SSexp2P.R ├── SSexp3P.R ├── SSpower2P.R ├── SSpower3P.R ├── ggtrendline.R ├── predFit.R ├── stat_eq.R ├── stat_rrp.R └── trendline_sum.R ├── README.md ├── ggtrendline.Rproj └── man ├── SSexp2P.Rd ├── SSexp3P.Rd ├── SSpower2P.Rd ├── SSpower3P.Rd ├── ggtrendline.Rd ├── predFit.Rd ├── stat_eq.Rd ├── stat_rrp.Rd └── trendline_sum.Rd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^ggtrendline\.Rproj$ 2 | ^\.Rproj\.user$ 3 | -------------------------------------------------------------------------------- /.Rhistory: -------------------------------------------------------------------------------- 1 | library(devtools) 2 | load_all() 3 | document() 4 | load_all() 5 | document() 6 | load_all() 7 | document() 8 | library(ggtrendline) 9 | x <- c(1, 3, 6, 9, 13, 17) 10 | y <- c(5, 8, 11, 13, 13.2, 13.5) 11 | ggtrendline(x, y, model = "line2P") # default 12 | ggtrendline(x, y, model = "log2P", CI.fill = NA) # CI lines only, without CI filling 13 | ggtrendline(x, y, model = "exp2P", linecolor = "blue", linetype = 1, linewidth = 1) # set line 14 | ggtrendline(x, y, model = "exp3P", CI.level = 0.99, 15 | CI.fill = "red", CI.alpha = 0.1, CI.color = NA, CI.lty = 2, CI.lwd = 1.5) # set CI 16 | ?logLik 17 | x<-1:5 18 | y<-c(2,4,8,20,25) 19 | xy<-data.frame(x,y) 20 | getInitial(y ~ SSexp2P(x,a,b), data = xy) 21 | ## Initial values are in fact the converged values 22 | fitexp2P <- nls(y~SSexp2P(x,a,b), data=xy) 23 | summary(fitexp2P) 24 | logLik(fitexp2P) 25 | logLik(fitexp2P)[1] 26 | logLik(fitexp2P)[1]->ddd 27 | typeof(ddd) 28 | as.numeric(ddd) 29 | typeof(ddd) 30 | as.numeric(ddd)->ccc 31 | typeof(ccc) 32 | length(x) 33 | x2<-1:10 34 | length(x2) 35 | ggtrendline(x2,y) 36 | nrow(z) 37 | z<-data.frame(x,y) 38 | z<-na.omit(z) 39 | nrow = nrow(z) 40 | nrow(z) 41 | logLik.fit <- stats::logLik(fit) 42 | fit<-lm(y~x) 43 | logLik.fit <- stats::logLik(fit) 44 | logLik.fit 45 | logLik.fit <- logLik.fit[1] 46 | logLik.fit 47 | npar 48 | napr=3 49 | -2*logLik.fit+2*npar*(nrow/(nrow-npar-1)) 50 | npar=3 51 | -2*logLik.fit+2*npar*(nrow/(nrow-npar-1)) 52 | load_all() 53 | document() 54 | library(devtools) 55 | load_all() 56 | document() 57 | check() 58 | build() 59 | remove.packages("ggtrendline") 60 | install.packages("F:/R/ggtrendline_1.0.3.tar.gz",repos = NULL, type = "source") 61 | library(devtools) 62 | load_all() 63 | document() 64 | check() 65 | build() 66 | build() 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: ggtrendline 2 | Version: 1.0.3 3 | Date: 2022-04-24 4 | Title: Add Trendline and Confidence Interval to 'ggplot' 5 | Authors@R: c( 6 | person("Weiping", "Mei", role = c("aut", "cre", "cph"), email = "meiweipingg@163.com"), 7 | person("Guangchuang", "Yu", role = "aut"), 8 | person("Brandon M.", "Greenwell", role = "aut"), 9 | person("Jiangshan", "Lai", role = "ctb"), 10 | person("Zhendu", "Mao", role = "ctb"), 11 | person("Yu", "Umezawa", role = "ctb"), 12 | person("Jun", "Zeng", role = "ctb"), 13 | person("Jun", "Wang", role = "ctb") 14 | ) 15 | Maintainer: Weiping Mei 16 | Description: Add trendline and confidence interval of linear or nonlinear regression model and 17 | show equation to 'ggplot' as simple as possible. For a general overview of the methods used in 18 | this package, see Ritz and Streibig (2008) and 19 | Greenwell and Schubert Kabban (2014) . 20 | Depends: R (>= 3.5.2) 21 | Imports: stats, ggplot2 22 | Suggests: investr, AICcmodavg 23 | BugReports: https://github.com/PhDMeiwp/ggtrendline/issues 24 | License: GPL-3 25 | URL: https://github.com/PhDMeiwp/ggtrendline 26 | LazyLoad: true 27 | LazyData: true 28 | RoxygenNote: 7.1.2 29 | Encoding: UTF-8 30 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(predFit,default) 4 | S3method(predFit,nls) 5 | export(SSexp2P) 6 | export(SSexp3P) 7 | export(SSpower2P) 8 | export(SSpower3P) 9 | export(ggtrendline) 10 | export(predFit) 11 | export(stat_eq) 12 | export(stat_rrp) 13 | export(trendline_sum) 14 | import(ggplot2) 15 | import(stats) 16 | -------------------------------------------------------------------------------- /R/.Rhistory: -------------------------------------------------------------------------------- 1 | library(devtools) 2 | load_all() 3 | document() 4 | check() 5 | build() 6 | load_all() 7 | document() 8 | check() 9 | build() 10 | -------------------------------------------------------------------------------- /R/SSexp2P.R: -------------------------------------------------------------------------------- 1 | #' Self-Starting Nls 'exp2P' Regression Model 2 | #' 3 | #' This selfStart model evaluates the power regression function (formula as: y=a*exp(b*x)). It has an initial attribute that will evaluate initial estimates of the parameters 'a' and 'b' for a given set of data. 4 | #' 5 | #' @usage SSexp2P(predictor, a, b) 6 | #' @param predictor a numeric vector of values at which to evaluate the model. 7 | #' @param a,b The numeric parameters responding to the exp2P model. 8 | #' @export 9 | #' @return No return value (called for side effects). 10 | #' @examples 11 | #' library(ggtrendline) 12 | #' x<-1:5 13 | #' y<-c(2,4,8,20,25) 14 | #' xy<-data.frame(x,y) 15 | #' getInitial(y ~ SSexp2P(x,a,b), data = xy) 16 | #' ## Initial values are in fact the converged values 17 | #' 18 | #' fitexp2P <- nls(y~SSexp2P(x,a,b), data=xy) 19 | #' summary(fitexp2P) 20 | #' 21 | #' prediction <- predFit(fitexp2P , data.frame(x=x), se.fit = TRUE, 22 | #' level = 0.95, interval = "confidence") 23 | #' yfitexp2P <- prediction$fit 24 | #' yfitexp2P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 25 | #' 26 | #' @seealso \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 27 | 28 | 29 | # selfStart method for exp2P model (formula as y = a *exp(b*x)) 30 | SSexp2P<-selfStart( 31 | function(predictor,a,b){a*exp(b*predictor)}, 32 | function(mCall,LHS, data, ...) # added '...' to meet the update in 'nls' function in R package 'stats'. 33 | { 34 | xy <- sortedXyData(mCall[["predictor"]],LHS, data) 35 | 36 | if (min(xy[,"y"])>0){ 37 | lmFit <- lm(log(xy[,"y"]) ~ xy[,"x"]) 38 | coefs <- coef(lmFit) 39 | a <- exp(coefs[1]) #intercept 40 | b <- coefs[2] #slope 41 | value <- c(a, b) 42 | names(value) <- mCall[c("a","b")] 43 | value 44 | }else{stop(" 45 | >>Try to use other selfStart functions. 46 | Because the 'SSexp2P' function need ALL x values greater than 0.") 47 | } 48 | },c("a","b")) 49 | 50 | # getInitial(y~SSexp2P(x,a,b),data = xy) 51 | -------------------------------------------------------------------------------- /R/SSexp3P.R: -------------------------------------------------------------------------------- 1 | #' Self-Starting Nls 'exp3P' Regression Model 2 | #' 3 | #' This selfStart model evaluates the exponential regression function (formula as: y=a*exp(b*x)+c). It has an initial attribute that will evaluate initial estimates of the parameters a, b, and c for a given set of data. 4 | #' 5 | #' @usage SSexp3P(predictor, a, b, c) 6 | #' @param predictor a numeric vector of values at which to evaluate the model. 7 | #' @param a,b,c Three numeric parameters responding to the exp3P model. 8 | #' @export 9 | #' @return No return value (called for side effects). 10 | #' @examples 11 | #' library(ggtrendline) 12 | #' x<-1:5 13 | #' y<-c(2,4,8,16,28) 14 | #' xy<-data.frame(x,y) 15 | #' getInitial(y ~ SSexp3P(x,a,b,c), data = xy) 16 | #' ## Initial values are in fact the converged values 17 | #' 18 | #' fitexp3P <- nls(y~SSexp3P(x,a,b,c), data=xy) 19 | #' summary(fitexp3P) 20 | #' 21 | #' prediction <- predFit(fitexp3P , data.frame(x=x), se.fit = TRUE, 22 | #' level = 0.95, interval = "confidence") 23 | #' yfitexp3P <- prediction$fit 24 | #' yfitexp3P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 25 | #' 26 | #' @seealso \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 27 | 28 | # selfStart method for exp3P model (formula as y = a *exp(b*x)+ c) 29 | SSexp3P<-selfStart( 30 | function(predictor,a,b,c){a*exp(b*predictor)+c}, 31 | function(mCall,LHS, data, ...) # added '...' 32 | { 33 | xy <- sortedXyData(mCall[["predictor"]],LHS, data) 34 | y=xy[,"y"] 35 | x=xy[,"x"] 36 | adjy=y-min(y)+1 37 | xadjy=data.frame(x,adjy) 38 | 39 | lmFit <- lm(log(adjy) ~ x) 40 | coefs <- coef(lmFit) 41 | get.b <- coefs[2] #slope 42 | 43 | nlsFit<-nls(adjy~cbind(1+exp(b*x),exp(b*x)), 44 | start = list(b=get.b),data = xadjy,algorithm = "plinear", 45 | nls.control(maxiter = 5000000,minFactor = 10^(-10))) 46 | 47 | coef<-coef(nlsFit) 48 | b<-coef[1] 49 | c<-coef[2]+min(y)-1 50 | a<-coef[3]+coef[2] 51 | 52 | value <- c(a,b,c) 53 | names(value) <- mCall[c("a","b","c")] 54 | value 55 | },c("a","b","c")) 56 | 57 | # getInitial(y~SSexp3P(x,a,b,c),data = z) 58 | -------------------------------------------------------------------------------- /R/SSpower2P.R: -------------------------------------------------------------------------------- 1 | #' Self-Starting Nls 'power2P' Regression Model 2 | #' 3 | #' This selfStart model evaluates the power regression function (formula as: y=a*x^b). It has an initial attribute that will evaluate initial estimates of the parameters 'a' and 'b' for a given set of data. 4 | #' 5 | #' @usage SSpower2P(predictor, a, b) 6 | #' @param predictor a numeric vector of values at which to evaluate the model. 7 | #' @param a,b The numeric parameters responding to the exp2P model. 8 | #' @export 9 | #' @return No return value (called for side effects). 10 | #' @examples 11 | #' library(ggtrendline) 12 | #' x<-1:5 13 | #' y<-c(2,4,8,20,25) 14 | #' xy<-data.frame(x,y) 15 | #' getInitial(y ~ SSpower2P(x,a,b), data = xy) 16 | #' ## Initial values are in fact the converged values 17 | #' 18 | #' fitpower2P <- nls(y~SSpower2P(x,a,b), data=xy) 19 | #' summary(fitpower2P) 20 | #' 21 | #' prediction <- predFit(fitpower2P , data.frame(x=x), se.fit = TRUE, 22 | #' level = 0.95, interval = "confidence") 23 | #' yfitpower2P <- prediction$fit 24 | #' yfitpower2P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 25 | #' 26 | #' @seealso \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 27 | 28 | 29 | # selfStart method for power2P model (formula as y = a *x^b) 30 | SSpower2P<-selfStart( 31 | function(predictor,a,b){a*predictor^b}, 32 | function(mCall,LHS, data, ...) # added '...' 33 | { 34 | xy <- sortedXyData(mCall[["predictor"]],LHS, data) 35 | 36 | if (min(xy[,"x"])>0){ 37 | lmFit <- lm(log(xy[,"y"]) ~ log(xy[,"x"])) # both x and adjy values should be greater than 0. 38 | coefs <- coef(lmFit) 39 | a <- exp(coefs[1]) #intercept 40 | b <- coefs[2] #slope 41 | 42 | value <- c(a,b) 43 | names(value) <- mCall[c("a","b")] 44 | value 45 | 46 | }else{stop(" 47 | >>Try to use other selfStart functions. 48 | Because the 'SSpower2P' function need ALL x values greater than 0.") 49 | } 50 | },c("a","b")) 51 | 52 | # getInitial(y~SSpower2P(x,a,b),data = xy) 53 | -------------------------------------------------------------------------------- /R/SSpower3P.R: -------------------------------------------------------------------------------- 1 | #' Self-Starting Nls 'power3P' Regression Model 2 | #' 3 | #' This selfStart model evaluates the power regression function (formula as: y=a*x^b+c). It has an initial attribute that will evaluate initial estimates of the parameters a, b, and c for a given set of data. 4 | #' 5 | #' @usage SSpower3P(predictor, a, b, c) 6 | #' @param predictor a numeric vector of values at which to evaluate the model. 7 | #' @param a,b,c Three numeric parameters responding to the exp3P model. 8 | #' @export 9 | #' @return No return value (called for side effects). 10 | #' @examples 11 | #' library(ggtrendline) 12 | #' x<-1:5 13 | #' y<-c(2,4,8,20,25) 14 | #' xy<-data.frame(x,y) 15 | #' getInitial(y ~ SSpower3P(x,a,b,c), data = xy) 16 | #' ## Initial values are in fact the converged values 17 | #' 18 | #' fitpower3P <- nls(y~SSpower3P(x,a,b,c), data=xy) 19 | #' summary(fitpower3P) 20 | #' 21 | #' prediction <- predFit(fitpower3P , data.frame(x=x), se.fit = TRUE, 22 | #' level = 0.95, interval = "confidence") 23 | #' yfitpower3P <- prediction$fit 24 | #' yfitpower3P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 25 | #' 26 | #' @seealso \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 27 | 28 | # selfStart method for power3P model (formula as y = a *x^b+ c) 29 | SSpower3P<-selfStart( 30 | function(predictor,a,b,c){a*predictor^b+c}, 31 | function(mCall,LHS, data, ...) # added '...' 32 | { 33 | xy <- sortedXyData(mCall[["predictor"]],LHS, data) 34 | y=xy[,"y"] 35 | x=xy[,"x"] 36 | 37 | if (min(x)>0){ 38 | 39 | adjy=y-min(y)+1 40 | xadjy=data.frame(x,adjy) 41 | 42 | lmFit <- lm(log(adjy) ~ log(x)) # both x and adjy values should be greater than 0. 43 | coefs <- coef(lmFit) 44 | get.b <- coefs[2] #slope 45 | 46 | nlsFit<-nls(adjy~cbind(1+x^b,x^b), 47 | start = list(b=get.b),data = xadjy,algorithm = "plinear", 48 | nls.control(maxiter = 5000000,minFactor = 10^(-10))) 49 | 50 | coef<-coef(nlsFit) 51 | b<-coef[1] 52 | c<-coef[2]+min(y)-1 53 | a<-coef[3]+coef[2] 54 | 55 | value <- c(a,b,c) 56 | names(value) <- mCall[c("a","b","c")] 57 | value 58 | 59 | }else{stop(" 60 | >>Try to use other selfStart functions. 61 | Because the 'SSpower3P' function need ALL x values greater than 0.") 62 | } 63 | },c("a","b","c")) 64 | 65 | # getInitial(y~SSpower3P(x,a,b,c),data = xy) 66 | -------------------------------------------------------------------------------- /R/ggtrendline.R: -------------------------------------------------------------------------------- 1 | #' Add Trendline and Confidence Interval to 'ggplot' 2 | #' 3 | #' Add trendline and confidence interval of linear or nonlinear regression model to 'ggplot', 4 | #' by using different models built in the 'ggtrendline()' function. \cr The function includes the following models:\cr 5 | #' "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 6 | #' 7 | #' @param x,y the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable. 8 | #' @param model select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c 9 | #' 10 | #' @param linecolor the color of regression line. Default is "black". 11 | #' @param linetype the type of regression line. Default is 1. Notes: linetype can be specified using either text c("blank","solid","dashed","dotted","dotdash","longdash","twodash") or number c(0, 1, 2, 3, 4, 5, 6). 12 | #' @param linewidth the width of regression line. Default is 0.6. 13 | #' 14 | #' @param CI.level level of confidence interval to use. Default is 0.95. 15 | #' @param CI.fill the color for filling the confidence interval. Default is "grey60". 16 | #' @param CI.alpha alpha value of filling color of confidence interval. Default is 0.3. 17 | #' @param CI.color line color of confidence interval. Default is "black". 18 | #' @param CI.lty line type of confidence interval. Default is 2. 19 | #' @param CI.lwd line width of confidence interval. Default is 0.5. 20 | #' 21 | #' @param summary summarizing the model fits. Default is TRUE. 22 | #' 23 | #' @param show.eq whether to show the regression equation, the value is one of c("TRUE", "FALSE"). 24 | #' @param yhat whether to add a hat symbol (^) on the top of "y" in equation. Default is FALSE. 25 | #' @param eq.x,eq.y equation position. 26 | #' 27 | #' @param Pvalue.corrected if P-value corrected or not, the value is one of c("TRUE", "FALSE"). 28 | #' @param show.Rsquare whether to show the R-square, the value is one of c("TRUE", "FALSE"). 29 | #' @param show.pvalue whether to show the P-value, the value is one of c("TRUE", "FALSE"). 30 | #' @param Rname to specify the character of R-square, the value is one of c(0, 1), corresponding to c(r^2, R^2). 31 | #' @param Pname to specify the character of P-value, the value is one of c(0, 1), corresponding to c(p, P). 32 | #' @param rrp.x,rrp.y the position for R square and P value. 33 | #' @param text.col the color used for the equation text. 34 | #' @param eDigit the numbers of digits for R square and P value. Default is 3. 35 | #' @param eSize font size of R square and P value. Default is 3. 36 | #' @param xlab,ylab labels of x- and y-axis. 37 | #' 38 | #' @import stats 39 | #' @import ggplot2 40 | #' @export 41 | #' @return No return value (called for side effects). 42 | #' @details The values of each parameter of regression model can be found by typing \code{\link{trendline_sum}} function in this package.\cr\cr The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method). 43 | #' 44 | #' @references 45 | #' Ritz C., and Streibig J. C. (2007) 46 | #' \emph{Nonlinear Regression with R}. Springer. 47 | #' 48 | #' Greenwell B. M., and Schubert Kabban C. M. (2014) 49 | #' \emph{investr: An R Package for Inverse Estimation}. The R Journal, 6(1), 90-100. 50 | #' 51 | #' @examples 52 | #' # library(ggplot2) 53 | #' library(ggtrendline) 54 | #' x <- c(1, 3, 6, 9, 13, 17) 55 | #' y <- c(5, 8, 11, 13, 13.2, 13.5) 56 | #' 57 | #' ggtrendline(x, y, model = "line2P") # default 58 | #' ggtrendline(x, y, model = "log2P", CI.fill = NA) # CI lines only, without CI filling 59 | #' 60 | #' ggtrendline(x, y, model = "exp2P", linecolor = "blue", linetype = 1, linewidth = 1) # set line 61 | #' ggtrendline(x, y, model = "exp3P", CI.level = 0.99, 62 | #' CI.fill = "red", CI.alpha = 0.1, CI.color = NA, CI.lty = 2, CI.lwd = 1.5) # set CI 63 | #' 64 | #' @seealso \code{\link{ggtrendline}}, \code{\link{stat_eq}}, \code{\link{stat_rrp}}, \code{\link{trendline_sum}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 65 | 66 | 67 | ggtrendline <- function(x, y, model="line2P", 68 | linecolor = "black", linetype = 1, linewidth = 0.6, 69 | CI.level = 0.95, CI.fill = "grey60", CI.alpha = 0.3, CI.color = "black", CI.lty = 2, CI.lwd = 0.5, 70 | summary = TRUE, 71 | show.eq = TRUE, 72 | yhat = FALSE, eq.x = NULL, eq.y = NULL, 73 | show.Rsquare = TRUE, show.pvalue = TRUE, Pvalue.corrected = TRUE, 74 | Rname = 0, Pname = 0, rrp.x = NULL, rrp.y = NULL, 75 | text.col="black", eDigit = 3, eSize = 3, 76 | xlab=NULL, ylab=NULL) 77 | { 78 | model=model 79 | if(is.null(xlab)) xlab = deparse(substitute(x)) else xlab = xlab 80 | if(is.null(ylab)) ylab = deparse(substitute(y)) else ylab = ylab 81 | 82 | OK <- complete.cases(x, y) 83 | x <- x[OK] 84 | y <- y[OK] 85 | z<-data.frame(x,y) 86 | 87 | xxx <- seq(min(x), max(x), len=100) 88 | 89 | # 1) model="line2P" 90 | if (model== c("line2P")) 91 | {formula = 'y = a*x + b' 92 | fit <- lm(y~x) 93 | 94 | prediction <- stats::predict(fit, data.frame(x=xxx), se.fit = TRUE, 95 | level = CI.level, interval = "confidence") 96 | yfit <- prediction$fit 97 | } 98 | 99 | # 2) model="line3P" 100 | if (model== c("line3P")) 101 | { formula = 'y = a*x^2 + b*x + c' 102 | fit<-lm(y~I(x^2)+x) 103 | 104 | prediction <- stats::predict(fit, data.frame(x=xxx), se.fit = TRUE, 105 | level = CI.level, interval = "confidence") 106 | yfit <- prediction$fit 107 | } 108 | 109 | # 3) model="log2P" 110 | if (model== c("log2P")) 111 | { formula = 'y = a*ln(x) + b' 112 | 113 | if (min(x)>0) 114 | { fit<-lm(y~log(x)) 115 | 116 | prediction <- stats::predict(fit, data.frame(x=xxx), se.fit = TRUE, 117 | level = CI.level, interval = "confidence") 118 | yfit <- prediction$fit 119 | }else{ 120 | stop(" 121 | 'log2P' model need ALL x values greater than 0. Try other models.") 122 | } 123 | } 124 | 125 | # 4.2) model="exp2P" 126 | if (model== c("exp2P")) 127 | { formula = 'y = a*exp(b*x)' 128 | fit<-nls(y~SSexp2P(x,a,b),data=z) 129 | 130 | prediction <- predFit(fit, data.frame(x=xxx), se.fit = TRUE, 131 | level = CI.level, interval = "confidence") 132 | yfit <- prediction$fit 133 | } 134 | 135 | # 4.3) model="exp3P" 136 | if (model== c("exp3P")) 137 | { formula = 'y = a*exp(b*x) + c' 138 | fit<-nls(y~SSexp3P(x,a,b,c),data=z) 139 | 140 | prediction <- predFit(fit, data.frame(x=xxx), se.fit = TRUE, 141 | level = CI.level, interval = "confidence") 142 | yfit <- prediction$fit 143 | } 144 | 145 | # 5.2) model="power2P" 146 | if (model== c("power2P")) 147 | { formula = 'y = a*x^b' 148 | 149 | if (min(x)>0){ 150 | fit<-nls(y~SSpower2P(x,a,b),data=z) 151 | 152 | prediction <- predFit(fit, data.frame(x=xxx), se.fit = TRUE, 153 | level = CI.level, interval = "confidence") 154 | yfit <- prediction$fit 155 | }else{ 156 | stop(" 157 | 'power2P' model need ALL x values greater than 0. Try other models.") 158 | } 159 | } 160 | 161 | # 5.3) model="power3P" 162 | if (model== c("power3P")) 163 | { formula = 'y = a*x^b + c' 164 | 165 | if (min(x)>0){ 166 | fit<-nls(y~SSpower3P(x,a,b,c),data=z) 167 | 168 | prediction <- predFit(fit, data.frame(x=xxx), se.fit = TRUE, 169 | level = CI.level, interval = "confidence") 170 | yfit <- prediction$fit 171 | }else{ 172 | stop(" 173 | 'power3P' model need ALL x values greater than 0. Try other models.") 174 | } 175 | 176 | # 100) beyond the built-in models. 177 | 178 | }else{ 179 | Check<-c("line2P","line3P","log2P","exp2P","exp3P","power2P","power3P") 180 | if (!model %in% Check) 181 | stop(" 182 | \"model\" should be one of c(\"lin2P\",\"line3P\",\"log2P\",\"exp2P\",\"exp3P\",\"power2P\",\"power3P\").") 183 | } 184 | 185 | if (summary==TRUE){ 186 | trendline_sum(x=x, y=y, model=model, Pvalue.corrected = Pvalue.corrected, eDigit = eDigit) 187 | }else{} 188 | 189 | 190 | if (requireNamespace("ggplot2", quietly = TRUE)){ 191 | gg1 <- ggplot(NULL, aes(x = xxx))+ 192 | geom_ribbon(aes(x = xxx, ymin = yfit[,2], ymax = yfit[,3]), fill=CI.fill, color= CI.color, alpha = CI.alpha, linetype = CI.lty, size = CI.lwd) + 193 | geom_line(aes(x = xxx, y = yfit[,1]), color = linecolor, linetype = linetype, size = linewidth)+ 194 | 195 | stat_eq(x=x, y=y, model=model, 196 | show.eq = show.eq, xname = "x", yname = "y", yhat = yhat, 197 | eq.x = eq.x, eq.y = eq.y, text.col=text.col, eDigit = eDigit, eSize = eSize)+ 198 | 199 | stat_rrp(x=x, y=y, model=model, Pvalue.corrected = Pvalue.corrected, 200 | show.Rsquare = show.Rsquare, show.pvalue = show.pvalue, Rname = Rname, Pname = Pname, 201 | rrp.x = rrp.x , rrp.y = rrp.y , text.col=text.col, eDigit = eDigit , eSize = eSize)+ 202 | xlab(xlab) + ylab(ylab) 203 | gg1 # ggtrendline 204 | } 205 | 206 | } 207 | -------------------------------------------------------------------------------- /R/predFit.R: -------------------------------------------------------------------------------- 1 | #' Predictions from a Fitted Model 2 | #' 3 | #' Generic prediction method for various types of fitted models. \code{predFit} 4 | #' can be used to obtain standard errors of fitted values and 5 | #' adjusted/unadjusted confidence/prediction intervals for objects of class 6 | #' \code{"lm"}, \code{"nls"}. 7 | #' 8 | #' @param object An object that inherits from class \code{"lm"}, \code{"nls"}. 9 | #' @param newdata An optional data frame in which to look for variables with 10 | #' which to predict. If omitted, the fitted values are used. 11 | #' @param se.fit A logical vaue indicating if standard errors are required. 12 | #' Default is \code{FALSE}. 13 | #' @param interval Type of interval to be calculated. Can be one of "none" 14 | #' (default), "confidence", or "prediction". Default is \code{"none"}. 15 | #' @param level A numeric scalar between 0 and 1 giving the confidence level for 16 | #' the intervals (if any) to be calculated. Default is \code{0.95}. 17 | #' @param adjust A logical value indicating if an adjustment should be made to 18 | #' the critical value used in calculating the confidence interval. This is 19 | #' useful for when the calibration curve is to be used multiple, say k, times. 20 | #' Default is \code{FALSE}. 21 | #' @param k The number times the calibration curve is to be used for computing 22 | #' a confidence/prediction interval. Only needed when 23 | #' \code{adjust = "Bonferroni"}. 24 | #' @param ... Additional optional arguments. At present, no optional arguments 25 | #' are used. 26 | #' 27 | #' @export 28 | #' @return No return value (called for side effects). 29 | #' @note predFit function is from 'investr' package written by Brandon M. Greenwell. 30 | #' 31 | #' @references 32 | #' Greenwell B. M., and Schubert-Kabban, C. M. (2014) 33 | #' \emph{investr: An R Package for Inverse Estimation}. The R Journal, 6(1), 90-100. 34 | #' 35 | #' @seealso \code{\link[investr]{predFit}} 36 | 37 | predFit <- function(object, ...) { 38 | UseMethod("predFit") 39 | } 40 | 41 | #' @rdname predFit 42 | #' @export 43 | predFit.default <- function(object, ...) { 44 | stats::predict(object, ...) 45 | } 46 | 47 | #' @rdname predFit 48 | #' @export 49 | predFit.nls <- function(object, newdata, se.fit = FALSE, 50 | interval = c("none", "confidence", "prediction"), 51 | level = 0.95, 52 | adjust = c("none", "Bonferroni", "Scheffe"), k, 53 | ...) { 54 | 55 | # Match arguments 56 | interval <- match.arg(interval) 57 | adjust <- match.arg(adjust) 58 | 59 | # Make sure se.fit is set to TRUE if intervals are requested 60 | compute.se.fit <- if (se.fit || (interval != "none")) { 61 | TRUE 62 | } else { 63 | FALSE 64 | } 65 | 66 | # No support for the Golub-Pereyra algorithm for partially linear 67 | # least-squares models 68 | if (interval != "none") { 69 | if (!is.null(object$call$algorithm) && object$call$algorithm == "plinear") { 70 | stop(paste0("The Golub-Pereyra algorithm for partially linear least-", 71 | "squares models is currently not supported."), call. = FALSE) 72 | } 73 | } 74 | 75 | # Prediction data 76 | newdata <- if (missing(newdata)) { 77 | eval(stats::getCall(object)$data, envir = parent.frame()) 78 | } else { 79 | as.data.frame(newdata) 80 | } 81 | if (is.null(newdata)) { 82 | stop("No data available for predictions.", call. = FALSE) 83 | } 84 | 85 | # Name of independent variable 86 | xname <- intersect(all.vars(stats::formula(object)[[3]]), colnames(newdata)) 87 | 88 | # Predicted values 89 | pred <- object$m$predict(newdata) 90 | 91 | # Compute standard error 92 | if (compute.se.fit) { 93 | 94 | # Assign values to parameter names in current environment 95 | param.names <- names(stats::coef(object)) 96 | for (i in 1:length(param.names)) { 97 | assign(param.names[i], stats::coef(object)[i]) 98 | } 99 | 100 | # Assign values to independent variable name 101 | assign(xname, newdata[, xname]) 102 | 103 | # Calculate gradient (numerically) 104 | form <- object$m$formula() 105 | rhs <- eval(form[[3]]) 106 | if (is.null(attr(rhs, "gradient"))) { 107 | f0 <- attr(stats::numericDeriv(form[[3]], param.names), "gradient") 108 | } else { # self start models should have gradient attribute 109 | f0 <- attr(rhs, "gradient") 110 | } 111 | 112 | # Calculate standard error 113 | R1 <- object$m$Rmat() 114 | # v0 <- diag(f0 %*% solve(t(R1) %*% R1) %*% t(f0)) 115 | v0 <- diag(f0 %*% tcrossprod(solve(crossprod(R1)), f0)) # slightly faster 116 | se_fit <- sqrt(stats::sigma(object)^2 * v0) 117 | 118 | } 119 | 120 | # Compute results 121 | if (interval == "none") { 122 | 123 | # Vector of fitted/predicted values 124 | res <- pred 125 | 126 | } else { 127 | 128 | # Adjustment for simultaneous inference 129 | crit <- if (adjust == "Bonferroni") { # Bonferroni adjustment 130 | 131 | stats::qt((level + 2*k - 1) / (2*k), stats::df.residual(object)) 132 | 133 | } else if (adjust == "Scheffe") { # Scheffe adjustment 134 | 135 | if (interval == "confidence") { 136 | p <- length(stats::coef(object)) # number of regression parameters 137 | # sqrt(p * stats::qf((level + 1) / 2, p, stats::df.residual(object))) 138 | sqrt(p * stats::qf(level, p, stats::df.residual(object))) 139 | } else { 140 | # sqrt(k * stats::qf((level + 1) / 2, k, stats::df.residual(object))) 141 | sqrt(k * stats::qf(level, k, stats::df.residual(object))) 142 | } 143 | 144 | } else { # no adjustment 145 | 146 | stats::qt((level + 1) / 2, stats::df.residual(object)) 147 | 148 | } 149 | 150 | # Interval calculations 151 | if (interval == "confidence") { # confidence limits for mean response 152 | lwr <- pred - crit * se_fit # lower limits 153 | upr <- pred + crit * se_fit # upper limits 154 | } else { # prediction limits for individual response 155 | lwr <- pred - crit * sqrt(stats::sigma(object)^2 + se_fit^2) # lower limits 156 | upr <- pred + crit * sqrt(stats::sigma(object)^2 + se_fit^2) # upper limits 157 | } 158 | 159 | # Store results in a matrix 160 | res <- cbind("fit" = pred, "lwr" = lwr, "upr" = upr) 161 | 162 | } 163 | 164 | # If standard errors of fitted values are requested, convert results to a list 165 | # and store additional information 166 | if (se.fit) { 167 | res <- list("fit" = if (interval != "none") res else pred, #res, 168 | "se.fit" = se_fit, 169 | "df" = stats::df.residual(object), 170 | "residual.scale" = stats::sigma(object)) 171 | } 172 | 173 | # Return results 174 | return(res) 175 | 176 | } 177 | -------------------------------------------------------------------------------- /R/stat_eq.R: -------------------------------------------------------------------------------- 1 | #' Add Equation to 'ggplot' 2 | #' 3 | #' Add regression equation to 'ggplot', 4 | #' by using different models built in the 'ggtrendline()' function. The function includes the following models: \cr 5 | #' "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 6 | #' 7 | #' @param x,y the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable. 8 | #' @param model select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c 9 | #' @param show.eq whether to show the regression equation, the value is one of c("TRUE", "FALSE"). 10 | #' @param xname to specify the expression of "x" in equation, i.e., expression('x'), see Examples. 11 | #' @param yname to specify the expression of "y" in equation, i.e., expression('y'), see Examples. 12 | #' @param yhat whether to add a hat symbol (^) on the top of "y" in equation. Default is FALSE. 13 | #' @param eq.x,eq.y equation position. 14 | #' @param text.col the color used for the equation text. 15 | #' @param eDigit the numbers of digits for equation parameters. Default is 3. 16 | #' @param eSize font size of equation. Default is 3. 17 | #' @import ggplot2 18 | #' @export 19 | #' @return No return value (called for side effects). 20 | #' @details The values of each parameter of regression model can be found by typing \code{\link{trendline_sum}} function in this package.\cr\cr The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method). 21 | #' 22 | #' @seealso \code{\link{ggtrendline}}, \code{\link{stat_rrp}}, \code{\link{trendline_sum}} 23 | 24 | stat_eq <- function(x, y, model="line2P", 25 | show.eq = TRUE, xname = "x", yname = "y", yhat = FALSE, 26 | eq.x = NULL, eq.y = NULL, text.col="black", eDigit = 3, eSize = 3 27 | ) 28 | { 29 | model = model 30 | xname = substitute(xname) 31 | if(yhat == TRUE) yname = substitute(hat(yname)) else yname = substitute(yname) 32 | 33 | OK <- complete.cases(x, y) 34 | x <- x[OK] 35 | y <- y[OK] 36 | z <- data.frame(x,y) 37 | 38 | return <- trendline_sum(x=x, y=y, model=model, summary = FALSE, eDigit = eDigit) 39 | a = return$parameter$a 40 | b = return$parameter$b 41 | a = format(a, digits = eDigit) 42 | b = format(b, digits = eDigit) 43 | if (a==1){a=c("")} 44 | if (b==1){b=c("")} 45 | if (b==-1){b=c("-")} 46 | 47 | if (is.null(return$parameter$c)==FALSE){ 48 | c = return$parameter$c 49 | c = format(c, digits = eDigit) 50 | if (c==1){c=c("")} 51 | if (c==-1){c=c("-")} 52 | }else{} 53 | 54 | # 1) model="line2P" 55 | if (model== c("line2P")) 56 | { formula = 'y = a*x + b' 57 | 58 | if (b>=0) 59 | {param <- substitute(expression(italic(yname) == a~italic(xname) +b))[2] 60 | }else{ 61 | param <- substitute(expression(italic(yname) == a~italic(xname) ~b))[2] 62 | } 63 | } 64 | 65 | # 2) model="line3P" 66 | if (model== c("line3P")) 67 | { formula = 'y = a*x^2 + b*x + c' 68 | 69 | if (b>=0) 70 | { 71 | if(c>=0) 72 | {param <- substitute(expression(italic(yname) == a~italic(xname)^2 + b~italic(xname) +c))[2] 73 | }else{param <- substitute(expression(italic(yname) == a~italic(xname)^2 + b~italic(xname) ~c))[2] 74 | } 75 | }else{ 76 | if(c>=0) 77 | {param <- substitute(expression(italic(yname) == a~italic(xname)^2 ~b~italic(xname) +c))[2] 78 | }else{param <- substitute(expression(italic(yname) == a~italic(xname)^2 ~b~italic(xname) ~c))[2] 79 | } 80 | } 81 | } 82 | 83 | # 3) model="log2P" 84 | if (model== c("log2P")) 85 | { formula = 'y = a*ln(x) + b' 86 | 87 | if (min(x)>0) 88 | { 89 | if (b>=0) 90 | {param <- substitute(expression(italic(yname) == a~"ln(x)" +b))[2] 91 | }else{ 92 | param <- substitute(expression(italic(yname) == a~"ln(x)" ~b))[2] 93 | } 94 | 95 | }else{ 96 | stop(" 97 | 'log2P' model need ALL x values greater than 0. Try other models.") 98 | } 99 | } 100 | 101 | # 4.2) model="exp2P" 102 | if (model== "exp2P") 103 | { formula = 'y = a*exp(b*x)' 104 | param <- substitute(expression(italic(yname) == a~"e"^{b~italic(xname)}))[2] 105 | } 106 | 107 | 108 | # 4.3) model="exp3P" 109 | if (model== "exp3P") 110 | { formula = 'y = a*exp(b*x) + c' 111 | 112 | if (c>=0){ 113 | param <- substitute(expression(italic(yname) == a~"e"^{b~italic(xname)}~+c))[2] 114 | }else{ 115 | param <- substitute(expression(italic(yname) == a~"e"^{b~italic(xname)}~~c))[2] 116 | } 117 | } 118 | 119 | 120 | # 5.2) model="power2P" 121 | if (model== "power2P") 122 | {formula = 'y = a*x^b' 123 | 124 | if (min(x)>0){ 125 | param <- substitute(expression(italic(yname) == a~italic(xname)^b))[2] 126 | }else{ 127 | stop(" 128 | 'power2P' model need ALL x values greater than 0. Try other models.") 129 | } 130 | } 131 | 132 | 133 | # 5.3) model="power3P" 134 | if (model== "power3P") 135 | {formula = 'y = a*x^b + c' 136 | 137 | if (min(x)>0){ 138 | 139 | if (c>=0){ 140 | param <- substitute(expression(italic(yname) == a~italic(xname)^b ~+c))[2] 141 | }else{ 142 | param <- substitute(expression(italic(yname) == a~italic(xname)^b ~~c))[2] 143 | } 144 | 145 | }else{ 146 | stop(" 147 | 'power3P' model need ALL x values greater than 0. Try other models.") 148 | } 149 | 150 | # 100) beyond the built-in models. 151 | 152 | }else{ 153 | Check<-c("line2P","line3P","log2P","exp2P","exp3P","power2P","power3P") 154 | if (!model %in% Check) 155 | stop(" 156 | \"model\" should be one of c(\"lin2P\",\"line3P\",\"log2P\",\"exp2P\",\"exp3P\",\"power2P\",\"power3P\").") 157 | } 158 | 159 | ### add equation to 'ggplot' 160 | startx <- min(x)+(max(x)-min(x))*0.1 161 | starty <- max(y)+(max(y)-min(y))*0.1 162 | if (is.null(eq.x)) eq.x = startx else eq.x = eq.x 163 | if (is.null(eq.y)) eq.y = starty else eq.y = eq.y 164 | 165 | if (show.eq == TRUE) param = param else param = "" 166 | 167 | ggplot2::geom_text(data=NULL, aes(x=eq.x, y=eq.y, label = as.character(param)), parse = TRUE, color = text.col, size = eSize) 168 | } 169 | -------------------------------------------------------------------------------- /R/stat_rrp.R: -------------------------------------------------------------------------------- 1 | #' Add R square and P-value to 'ggplot' 2 | #' 3 | #' Add R-square and P-value of regression models to 'ggplot', 4 | #' by using models built in the 'ggtrendline()' function. The function includes the following models: \cr 5 | #' "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 6 | #' 7 | #' @param x,y the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable. 8 | #' @param model select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c 9 | #' @param Pvalue.corrected if P-value corrected or not, the value is one of c("TRUE", "FALSE"). 10 | #' @param show.Rsquare whether to show the R-square, the value is one of c("TRUE", "FALSE"). 11 | #' @param show.pvalue whether to show the P-value, the value is one of c("TRUE", "FALSE"). 12 | #' @param Rname to specify the character of R-square, the value is one of c(0, 1), corresponding to c(r^2, R^2). 13 | #' @param Pname to specify the character of P-value, the value is one of c(0, 1), corresponding to c(p, P). 14 | #' @param rrp.x,rrp.y the position for R square and P value. 15 | #' @param text.col the color used for the equation text. 16 | #' @param eDigit the numbers of digits for R square and P value. Default is 3. 17 | #' @param eSize font size of R square and P value. Default is 3. 18 | #' @import ggplot2 19 | #' @export 20 | #' @return No return value (called for side effects). 21 | #' @details The values of each parameter of regression model can be found by typing \code{\link{trendline_sum}} function in this package.\cr\cr The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method).\cr\cr The argument 'Pvalue.corrected' is only valid for non-linear regression.\cr\cr If "Pvalue.corrected = TRUE", the P-value is calculated by using "Residual Sum of Squares" and "Corrected Total Sum of Squares (i.e. sum((y-mean(y))^2))".\cr\cr If "Pvalue.corrected = FALSE", the P-value is calculated by using "Residual Sum of Squares" and "Uncorrected Total Sum of Squares (i.e. sum(y^2))". 22 | #' 23 | #' @seealso \code{\link{ggtrendline}}, \code{\link{stat_eq}}, \code{\link{trendline_sum}} 24 | 25 | stat_rrp <- function(x, y, model="line2P", Pvalue.corrected = TRUE, 26 | show.Rsquare = TRUE, show.pvalue = TRUE, 27 | Rname = 0, Pname = 0, 28 | rrp.x = NULL, rrp.y = NULL, text.col="black", eDigit = 3, eSize = 3 29 | ) 30 | { 31 | model = model 32 | if(Rname==0) Rname = "r" else Rname = "R" 33 | if(Pname==0) Pname = "p" else Pname = "P" 34 | 35 | OK <- complete.cases(x, y) 36 | x <- x[OK] 37 | y <- y[OK] 38 | z <- data.frame(x,y) 39 | 40 | return <- trendline_sum(x=x, y=y, model=model, Pvalue.corrected=Pvalue.corrected, summary = FALSE, eDigit = eDigit) 41 | 42 | if (return$p.value >= 0.0001){ 43 | pval <- return$p.value 44 | pval <- paste("=" , unname(pval)) 45 | }else{ 46 | pval <- "< 0.0001" 47 | } 48 | r2 <- return$R.squared 49 | adjr2<- return$adj.R.squared 50 | 51 | if (show.Rsquare == TRUE & show.pvalue == FALSE) param = substitute(expression(italic(Rname)^2 == r2))[2] 52 | if (show.Rsquare == FALSE & show.pvalue == TRUE) param =substitute(expression(italic(Pname)~~pval))[2] 53 | if (show.Rsquare == TRUE & show.pvalue == TRUE) param = substitute(expression(italic(Rname)^2 == r2*","~~italic(Pname)~~pval))[2] 54 | if (show.Rsquare == FALSE & show.pvalue == FALSE) param =NULL 55 | 56 | Check <- c("line2P","line3P","log2P","exp2P","exp3P","power2P","power3P") 57 | if (!model %in% Check) 58 | stop(" 59 | \"model\" should be one of c(\"lin2P\",\"line3P\",\"log2P\",\"exp2P\",\"exp3P\",\"power2P\",\"power3P\").") 60 | 61 | 62 | ### add R square and P value to 'ggplot' 63 | startx <- min(x)+(max(x)-min(x))*0.1 64 | starty <- max(y) 65 | if (is.null(rrp.x)) rrp.x = startx else rrp.x = rrp.x 66 | if (is.null(rrp.y)) rrp.y = starty else rrp.y = rrp.y 67 | 68 | ggplot2::geom_text(data=NULL, aes(x=rrp.x, y=rrp.y, label = as.character(param)), parse = TRUE, color = text.col, size = eSize) 69 | 70 | } 71 | -------------------------------------------------------------------------------- /R/trendline_sum.R: -------------------------------------------------------------------------------- 1 | #' Summarized Results of Each Regression Model 2 | #' 3 | #' Summarizing the results of linear or nonlinear regression model which built in the 'ggtrendline()' function. The function includes the following models:\cr 4 | #' "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 5 | #' 6 | #' @param x,y the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable. 7 | #' @param model select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c 8 | #' @param Pvalue.corrected if P-value corrected or not, the value is one of c("TRUE", "FALSE"). 9 | #' @param summary summarizing the model fits. Default is TRUE. 10 | #' @param eDigit the numbers of digits for summarized results. Default is 3. 11 | #' @import stats 12 | #' @export 13 | #' @details The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, \cr while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method).\cr\cr The argument 'Pvalue.corrected' is workful for non-linear regression only.\cr\cr If "Pvalue.corrected = TRUE", the P-vlaue is calculated by using "Residual Sum of Squares" and "Corrected Total Sum of Squares (i.e. sum((y-mean(y))^2))".\cr\cr If "Pvalue.corrected = TRUE", the P-vlaue is calculated by using "Residual Sum of Squares" and "Uncorrected Total Sum of Squares (i.e. sum(y^2))". 14 | #' @note If the output of 'AICc' is 'Inf', not an exact number, please try to expand the sample size of your dataset to >=6. 15 | #' 16 | #' @return R^2, indicates the R-Squared value of each regression model. 17 | #' @return p, indicates the p-value of each regression model. 18 | #' @return N, indicates the sample size. 19 | #' @return AIC, AICc, or BIC, indicate the Akaike's Information Criterion (AIC), the second-order AIC (AICc) for small samples, or Bayesian Information Criterion (BIC) for fitted model. Click \code{\link[stats]{AIC}} for details. The smaller the AIC, AICc or BIC, the better the model. 20 | #' @return RSS, indicate the value of "Residual Sum of Squares". 21 | #' 22 | #' @examples 23 | #' library(ggtrendline) 24 | #' x <- c(1, 3, 6, 9, 13, 17) 25 | #' y <- c(5, 8, 11, 13, 13.2, 13.5) 26 | #' 27 | #' trendline_sum(x, y, model="exp3P", summary=TRUE, eDigit=3) 28 | #' 29 | #' @seealso \code{\link{ggtrendline}}, \code{\link{SSexp2P}}, \code{\link{SSexp3P}}, \code{\link{SSpower2P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}}, \code{\link[AICcmodavg]{AICc}} 30 | 31 | trendline_sum <- function(x,y,model="line2P", Pvalue.corrected=TRUE, summary=TRUE, eDigit=5) 32 | { 33 | model=model 34 | 35 | OK <- complete.cases(x, y) 36 | x <- x[OK] 37 | y <- y[OK] 38 | z<-data.frame(x,y) 39 | z<-na.omit(z) 40 | nrow = nrow(z) 41 | 42 | # 1) model="line2P" 43 | if (model== c("line2P")) 44 | { 45 | Pvalue.corrected=TRUE 46 | 47 | formula = 'y = a*x + b' 48 | npar = 3 49 | 50 | fit<- lm(y~x) 51 | sum.line2P <- summary(fit) 52 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 53 | 54 | if (summary==TRUE){ 55 | print(sum.line2P,digits=eDigit) 56 | }else{} 57 | 58 | coeff<-sum.line2P$coefficients 59 | a<-coeff[2,1] # slope 60 | b<-coeff[1,1] # intercept 61 | 62 | n<-length(x) 63 | pval <- coeff[2,4] # p-value of parameter "a", indicates the p-value of whole model. 64 | pval<-unname(pval) 65 | r2 <- sum.line2P$r.squared 66 | adjr2<- sum.line2P$adj.r.squared 67 | 68 | a = format(a, digits = eDigit) 69 | b = format(b, digits = eDigit) 70 | r2 = format(r2, digits = eDigit) 71 | adjr2 = format(adjr2, digits = eDigit) 72 | pval = format(pval, digits = eDigit) 73 | 74 | a=as.numeric(a) 75 | b=as.numeric(b) 76 | param.out<- c(list("a"=a,"b"=b)) # for return values 77 | 78 | } 79 | 80 | # 2) model="line3P" 81 | if (model== c("line3P")) 82 | { 83 | Pvalue.corrected=TRUE 84 | 85 | formula = 'y = a*x^2 + b*x + c' 86 | npar = 4 87 | 88 | fit<-lm(y~I(x^2)+x) 89 | 90 | sum.line3P <- summary(fit) 91 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 92 | 93 | if (summary==TRUE){ 94 | print(sum.line3P,digits=eDigit) 95 | }else{} 96 | 97 | coeff<-coef(sum.line3P) 98 | a<-coeff[2,1] # slope of x.square 99 | b<-coeff[3,1] # slope of x 100 | c<-coeff[1,1] # intercept c 101 | 102 | n<-length(x) 103 | r2<-sum.line3P$r.squared 104 | adjr2 <- sum.line3P$adj.r.squared 105 | 106 | fstat<-sum.line3P$fstatistic 107 | pval<-pf(fstat[1], fstat[2], fstat[3], lower.tail=FALSE) #p-value of whole model. 108 | pval<-unname(pval) 109 | 110 | a = format(a, digits = eDigit) 111 | b = format(b, digits = eDigit) 112 | c = format(c, digits = eDigit) 113 | r2 = format(r2, digits = eDigit) 114 | adjr2 = format(adjr2, digits = eDigit) 115 | pval = format(pval, digits = eDigit) 116 | 117 | a=as.numeric(a) 118 | b=as.numeric(b) 119 | c=as.numeric(c) 120 | param.out<- c(list("a"=a,"b"=b,"c"=c)) 121 | } 122 | 123 | # 3) model="log2P" 124 | if (model== c("log2P")) 125 | { 126 | Pvalue.corrected=TRUE 127 | 128 | formula = 'y = a*ln(x) + b' 129 | npar = 3 130 | 131 | yadj<-y-min(y) #adjust 132 | 133 | if (min(x)>0) 134 | { 135 | if (summary==TRUE){ 136 | fit0<-lm(y~log(x)) 137 | sum.log0<-summary(fit0) 138 | ss.res<-sum((residuals(fit0))^2) # Residual Sum of Squares, DF= n-k 139 | print(sum.log0, digits = eDigit) 140 | }else{} 141 | 142 | fit<-lm(yadj~log(x)) # adjusted y used 143 | sum.log<-summary(fit) 144 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 145 | a<-sum.log$coefficients[2,1] # slope 146 | b<-sum.log$coefficients[1,1] # intercept 147 | b=b+min(y) #re-adjust 148 | 149 | fstat<-sum.log$fstatistic 150 | pval<-pf(fstat[1], fstat[2], fstat[3], lower.tail=FALSE) #p-value of whole model. 151 | pval<-unname(pval) 152 | 153 | n<-length(x) 154 | r2<-sum.log$r.squared 155 | adjr2 <- sum.log$adj.r.squared 156 | 157 | a = format(a, digits = eDigit) 158 | b = format(b, digits = eDigit) 159 | r2 = format(r2, digits = eDigit) 160 | adjr2 = format(adjr2, digits = eDigit) 161 | pval= format(pval, digits = eDigit) 162 | 163 | a=as.numeric(a) 164 | b=as.numeric(b) 165 | param.out<- c(list("a"=a,"b"=b)) 166 | 167 | }else{ 168 | stop(" 169 | 'log2P' model need ALL x values greater than 0. Try other models.") 170 | } 171 | } 172 | 173 | 174 | # 4.2) model="exp2P" 175 | if (model== c("exp2P")) 176 | { 177 | formula = 'y = a*exp(b*x)' 178 | npar = 3 179 | 180 | n=length(x) 181 | k = 2 # k means the count numbers of parameters(i.e., 'a', 'b' and 'c' in this case) 182 | 183 | fit<-nls(y~SSexp2P(x,a,b),data=z) 184 | sum.exp2P <- summary(fit) # Get the exact value of each parameter. 185 | 186 | ### calculate the F-statistic and p-value for model 187 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 188 | ss.total.uncor<-sum(y^2) # Uncorrected Total Sum of Squares, DF=n 189 | ss.total.cor<-sum((y-mean(y))^2) # Corrected Total Sum of Squares, DF=n-1 190 | 191 | if (Pvalue.corrected==TRUE){ 192 | ss.reg <- ss.total.cor - ss.res # Regression Sum of Squares, DF= (n-1)-(n-k) = k-1 in this case 193 | dfR= k-1 194 | }else{ 195 | ss.reg <- ss.total.uncor - ss.res # Regression Sum of Squares, DF= n-(n-k) = k in this case 196 | dfR= k 197 | } 198 | 199 | dfE= n-k # degrees of freedom for Error (or Residuals) 200 | 201 | Fval=(ss.reg/dfR)/(ss.res/dfE) 202 | pval=pf(Fval,dfR,dfE,lower.tail = F) 203 | pval<-unname(pval) 204 | 205 | RSE<-sum.exp2P$sigma # Residual standard error, type ?summary.nls in R for more detials. 206 | SSE<-(RSE^2)*(n-1) # Sum of Squares for Error, not equal to 'ss.res'. 207 | 208 | adjr2 <- 1-SSE/((var(y))*(n-1)) 209 | r2<-1-(1-adjr2)*((n-k)/(n-1)) 210 | 211 | if (summary==TRUE){ 212 | ### Start print step by step 213 | coeff = coef(sum.exp2P) 214 | # print 215 | cat("\nNonlinear regression model\n") 216 | cat("\nFormula: y = a*exp(b*x)","\n") 217 | df <- sum.exp2P$df 218 | rdf <- df[2L] 219 | cat("\nParameters:\n") 220 | printCoefmat(coeff, digits = eDigit) 221 | cat("\nResidual standard error:", 222 | format(sum.exp2P$sigma, digits = eDigit), "on", rdf, "degrees of freedom","\n") 223 | 224 | convInfo = fit$convInfo 225 | iterations<-convInfo$finIter 226 | tolerance<-convInfo$finTol 227 | 228 | cat("\nNumber of iterations to convergence:", 229 | format(iterations, digits = eDigit)) 230 | cat("\nAchieved convergence tolerance:",format(tolerance, digits = eDigit),"\n") 231 | 232 | cat("\nMultiple R-squared:", 233 | format(r2, digits = eDigit), ", Adjusted R-squared: ", 234 | format(adjr2, digits = eDigit)) 235 | cat("\nF-statistic:", 236 | format(Fval, digits = eDigit), "on", dfR, "and", dfE, "DF, ", "p-value:", format(pval, digits = eDigit), "\n") 237 | ### finished print 238 | }else{} 239 | 240 | coeffs<-sum.exp2P$coefficients 241 | a<-coeffs[1,1] 242 | b<-coeffs[2,1] 243 | 244 | a = format(a, digits = eDigit) 245 | b = format(b, digits = eDigit) 246 | r2 = format(r2, digits = eDigit) 247 | adjr2 = format(adjr2, digits = eDigit) 248 | pval= format(pval, digits = eDigit) 249 | 250 | a=as.numeric(a) 251 | b=as.numeric(b) 252 | param.out<- c(list("a"=a,"b"=b)) 253 | 254 | } 255 | 256 | # 4.3) model="exp3P" 257 | if (model== c("exp3P")) 258 | { 259 | formula = 'y = a*exp(b*x) + c' 260 | npar = 4 261 | 262 | yadj<-y-min(y)+1 263 | zzz<-data.frame(x,yadj) 264 | 265 | n=length(x) 266 | k = 3 # k means the count numbers of parameters(i.e., 'a', 'b' and 'c' in this case) 267 | 268 | # use selfStart function 'SSexp3P' for y = a *exp(b*x)+ c 269 | # fit model 270 | fit<-nls(yadj~SSexp3P(x,a,b,c),data=zzz) # use 'yadj', in case of extreme high y-values with low range, such as y= c(600002,600014,600018,600019,600020). 271 | sum.exp3P <- summary(fit) # Get the exact value of each parameter. 272 | 273 | ### calculate the F-statistic and p-value for model 274 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 275 | ss.total.uncor<-sum(y^2) # Uncorrected Total Sum of Squares, DF=n 276 | ss.total.cor<-sum((y-mean(y))^2) # Corrected Total Sum of Squares, DF=n-1 277 | 278 | if (Pvalue.corrected==TRUE){ 279 | ss.reg <- ss.total.cor - ss.res # Regression Sum of Squares, DF= (n-1)-(n-k) = k-1 in this case 280 | dfR= k-1 281 | }else{ 282 | ss.reg <- ss.total.uncor - ss.res # Regression Sum of Squares, DF= n-(n-k) = k in this case 283 | dfR= k 284 | } 285 | 286 | dfE= n-k # degrees of freedom for Error (or Residuals) 287 | 288 | Fval=(ss.reg/dfR)/(ss.res/dfE) 289 | pval=pf(Fval,dfR,dfE,lower.tail = F) 290 | pval<-unname(pval) 291 | 292 | RSE<-sum.exp3P$sigma # Residual standard error, type ?summary.nls in R for more detials. 293 | SSE<-(RSE^2)*(n-1) # Sum of Squares for Error, not equal to 'ss.res'. 294 | 295 | adjr2 <- 1-SSE/((var(y))*(n-1)) 296 | r2<-1-(1-adjr2)*((n-k)/(n-1)) 297 | 298 | if (summary==TRUE){ 299 | ### Start print step by step 300 | #re-adjust the output of coefficients. 301 | coeffadj = coef(sum.exp3P) 302 | ab.param<-coeffadj[1:2,] 303 | # re-adjust the Estimate value of parameter c 304 | c.param<-coeffadj[3,] 305 | c.p1<-c.param[1] 306 | c.p1 = c.p1 + min(y)-1 # re-adjust 'Estimate' value 307 | c.se<-c.param[2] # Std.Error value 308 | c.tval<-c.p1/c.se #re-adjust 't-value' 309 | c.pval<-2 * pt(abs(c.tval), n-k, lower.tail = FALSE) #re-adjust 'p-value' 310 | c<-c(c.p1,c.se,c.tval,c.pval) # re-adjust 311 | coeff.re.adj<- rbind(ab.param,c) 312 | 313 | # print 314 | cat("\nNonlinear regression model\n") 315 | cat("\nFormula: y = a*exp(b*x) + c","\n") 316 | df <- sum.exp3P$df 317 | rdf <- df[2L] 318 | cat("\nParameters:\n") 319 | printCoefmat(coeff.re.adj, digits = eDigit) 320 | cat("\nResidual standard error:", 321 | format(sum.exp3P$sigma, digits = eDigit), "on", rdf, "degrees of freedom","\n") 322 | 323 | convInfo = fit$convInfo 324 | iterations<-convInfo$finIter 325 | tolerance<-convInfo$finTol 326 | 327 | cat("\nNumber of iterations to convergence:", 328 | format(iterations, digits = eDigit)) 329 | cat("\nAchieved convergence tolerance:",format(tolerance, digits = eDigit),"\n") 330 | 331 | cat("\nMultiple R-squared:", 332 | format(r2, digits = eDigit), ", Adjusted R-squared: ", 333 | format(adjr2, digits = eDigit)) 334 | cat("\nF-statistic:", 335 | format(Fval, digits = eDigit), "on", dfR, "and", dfE, "DF, ", "p-value:", format(pval, digits = eDigit), "\n") 336 | ### finished print 337 | }else{} 338 | 339 | coeff<-sum.exp3P$coefficients 340 | a<-coeff[1,1] 341 | b<-coeff[2,1] 342 | c<-coeff[3,1]+min(y)-1 343 | 344 | a = format(a, digits = eDigit) 345 | b = format(b, digits = eDigit) 346 | c = format(c, digits = eDigit) 347 | r2 = format(r2, digits = eDigit) 348 | adjr2 = format(adjr2, digits = eDigit) 349 | pval= format(pval, digits = eDigit) 350 | 351 | a=as.numeric(a) 352 | b=as.numeric(b) 353 | c=as.numeric(c) 354 | param.out<- c(list("a"=a,"b"=b,"c"=c)) 355 | 356 | } 357 | 358 | 359 | # 5.2) model="power2P" 360 | if (model== c("power2P")) 361 | { 362 | formula = 'y = a*x^b' 363 | npar = 3 364 | 365 | n<-length(x) 366 | k = 2 # k means the count numbers of parameters (i.e., a, b and c in this case) 367 | 368 | if (min(x)>0){ 369 | # use selfStart function 'SSpower2P' for y = a *x^b 370 | # trendline model 371 | fit<-nls(y ~ SSpower2P(x,a,b),data=z) 372 | sum.power2P <- summary(fit) 373 | 374 | ### calculate the F-statistic and p-value for model 375 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 376 | ss.total.uncor<-sum(y^2) # Uncorrected Total Sum of Squares, DF=n 377 | ss.total.cor<-sum((y-mean(y))^2) # Corrected Total Sum of Squares, DF=n-1 378 | 379 | if (Pvalue.corrected==TRUE){ 380 | ss.reg <- ss.total.cor - ss.res # Regression Sum of Squares, DF= (n-1)-(n-k) = k-1 in this case 381 | dfR= k-1 382 | }else{ 383 | ss.reg <- ss.total.uncor - ss.res # Regression Sum of Squares, DF= n-(n-k) = k in this case 384 | dfR= k 385 | } 386 | 387 | dfE = n-k # degrees of freedom for Error (or Residuals) 388 | 389 | Fval = (ss.reg/dfR)/(ss.res/dfE) 390 | pval = pf(Fval,dfR,dfE,lower.tail = F) 391 | pval <- unname(pval) 392 | 393 | RSE<-sum.power2P$sigma # Residual standard error, type ?summary.nls in R for more detials. 394 | SSE<-(RSE^2)*(n-1) # Sum of Squares for Error, not equal to 'ss.res'. 395 | 396 | adjr2 <- 1-SSE/((var(y))*(n-1)) 397 | r2 <- 1-(1-adjr2)*((n-k)/(n-1)) 398 | 399 | if (summary==TRUE){ 400 | 401 | ### Start print step by step 402 | coeff = coef(sum.power2P) 403 | ab.param<-coeff[1:2,] 404 | 405 | # print 406 | cat("\nNonlinear regression model\n") 407 | cat("\nFormula: y = a*x^b","\n") 408 | df <- sum.power2P$df 409 | rdf <- df[2L] 410 | cat("\nParameters:\n") 411 | printCoefmat(coeff, digits = eDigit) 412 | cat("\nResidual standard error:", 413 | format(sum.power2P$sigma, digits = eDigit), "on", rdf, "degrees of freedom","\n") 414 | 415 | convInfo = fit$convInfo 416 | iterations<-convInfo$finIter 417 | tolerance<-convInfo$finTol 418 | 419 | cat("\nNumber of iterations to convergence:", 420 | format(iterations, digits = eDigit)) 421 | cat("\nAchieved convergence tolerance:",format(tolerance, digits = eDigit),"\n") 422 | 423 | cat("\nMultiple R-squared:", 424 | format(r2, digits = eDigit), ", Adjusted R-squared: ", 425 | format(adjr2, digits = eDigit)) 426 | cat("\nF-statistic:", 427 | format(Fval, digits = eDigit), "on", dfR, "and", dfE, "DF, ", "p-value:", format(pval, digits = eDigit), "\n") 428 | ### finished print 429 | }else{} 430 | 431 | coeffs<-sum.power2P$coefficients 432 | a<-coeffs[1,1] 433 | b<-coeffs[2,1] 434 | 435 | a = format(a, digits = eDigit) 436 | b = format(b, digits = eDigit) 437 | 438 | r2 = format(r2, digits = eDigit) 439 | adjr2 = format(adjr2, digits = eDigit) 440 | pval = format(pval, digits = eDigit) 441 | 442 | a=as.numeric(a) 443 | b=as.numeric(b) 444 | param.out<- c(list("a"=a,"b"=b)) 445 | }else{ 446 | stop(" 447 | 'power2P' model need ALL x values greater than 0. Try other models.") 448 | } 449 | } 450 | 451 | 452 | # 5.3) model="power3P" 453 | if (model== c("power3P")) 454 | { 455 | formula = 'y = a*x^b + c' 456 | npar = 4 457 | 458 | yadj<-y-min(y)+1 459 | zzz<-data.frame(x,yadj) 460 | 461 | n<-length(x) 462 | k = 3 # k means the count numbers of parameters (i.e., a, b and c in this case) 463 | 464 | if (min(x)>0){ 465 | # use selfStart function 'SSpower3P' for y = a *x^b+ c 466 | # trendline model 467 | fit<-nls(yadj~SSpower3P(x,a,b,c),data=zzz) # use 'yadj', in case of extreme high y-values with low range. 468 | sum.power3P <- summary(fit) 469 | 470 | ### calculate the F-statistic and p-value for model 471 | ss.res<-sum((residuals(fit))^2) # Residual Sum of Squares, DF= n-k 472 | ss.total.uncor<-sum(y^2) # Uncorrected Total Sum of Squares, DF=n 473 | ss.total.cor<-sum((y-mean(y))^2) # Corrected Total Sum of Squares, DF=n-1 474 | 475 | if (Pvalue.corrected==TRUE){ 476 | ss.reg <- ss.total.cor - ss.res # Regression Sum of Squares, DF= (n-1)-(n-k) = k-1 in this case 477 | dfR= k-1 478 | }else{ 479 | ss.reg <- ss.total.uncor - ss.res # Regression Sum of Squares, DF= n-(n-k) = k in this case 480 | dfR= k 481 | } 482 | 483 | dfE= n-k # degrees of freedom for Error (or Residuals) 484 | 485 | Fval=(ss.reg/dfR)/(ss.res/dfE) 486 | pval=pf(Fval,dfR,dfE,lower.tail = F) 487 | pval<-unname(pval) 488 | 489 | RSE<-sum.power3P$sigma # Residual standard error, type ?summary.nls in R for more detials. 490 | SSE<-(RSE^2)*(n-1) # Sum of Squares for Error, not equal to 'ss.res'. 491 | 492 | adjr2 <- 1-SSE/((var(y))*(n-1)) 493 | r2<-1-(1-adjr2)*((n-k)/(n-1)) 494 | 495 | if (summary==TRUE){ 496 | 497 | ### Start print step by step 498 | #re-adjust the output of coefficients. 499 | coeffadj = coef(sum.power3P) 500 | ab.param<-coeffadj[1:2,] 501 | # re-adjust the 'Estimate\ value of parameter 'c' 502 | c.param<-coeffadj[3,] 503 | c.p1<-c.param[1] 504 | c.p1 = c.p1 + min(y)-1 # re-adjust 505 | c.se<-c.param[2] # Std.Error value 506 | c.tval<-c.p1/c.se #re-adjust 't-value' 507 | c.pval<-2 * pt(abs(c.tval), n-k, lower.tail = FALSE) #re-adjust 'p-value' 508 | c<-c(c.p1,c.se,c.tval,c.pval) # re-adjust 509 | coeff.re.adj<- rbind(ab.param,c) 510 | 511 | # print 512 | cat("\nNonlinear regression model\n") 513 | cat("\nFormula: y = a*x^b + c","\n") 514 | df <- sum.power3P$df 515 | rdf <- df[2L] 516 | cat("\nParameters:\n") 517 | printCoefmat(coeff.re.adj, digits = eDigit) 518 | cat("\nResidual standard error:", 519 | format(sum.power3P$sigma, digits = eDigit), "on", rdf, "degrees of freedom","\n") 520 | 521 | convInfo = fit$convInfo 522 | iterations<-convInfo$finIter 523 | tolerance<-convInfo$finTol 524 | 525 | cat("\nNumber of iterations to convergence:", 526 | format(iterations, digits = eDigit)) 527 | cat("\nAchieved convergence tolerance:",format(tolerance, digits = eDigit),"\n") 528 | 529 | cat("\nMultiple R-squared:", 530 | format(r2, digits = eDigit), ", Adjusted R-squared: ", 531 | format(adjr2, digits = eDigit)) 532 | cat("\nF-statistic:", 533 | format(Fval, digits = eDigit), "on", dfR, "and", dfE, "DF, ", "p-value:", format(pval, digits = eDigit), "\n") 534 | ### finished print 535 | }else{} 536 | 537 | coeff<-sum.power3P$coefficients 538 | a<-coeff[1,1] 539 | b<-coeff[2,1] 540 | c<-coeff[3,1] 541 | c<-c+min(y)-1 #re-adjust 542 | 543 | a = format(a, digits = eDigit) 544 | b = format(b, digits = eDigit) 545 | c = format(c, digits = eDigit) 546 | r2 = format(r2, digits = eDigit) 547 | adjr2 = format(adjr2, digits = eDigit) 548 | pval = format(pval, digits = eDigit) 549 | 550 | a=as.numeric(a) 551 | b=as.numeric(b) 552 | c=as.numeric(c) 553 | param.out<- c(list("a"=a,"b"=b,"c"=c)) 554 | }else{ 555 | stop(" 556 | 'power3P' model need ALL x values greater than 0. Try other models.") 557 | } 558 | 559 | # 100) beyond the built-in models. 560 | 561 | }else{ 562 | Check<-c("line2P","line3P","log2P","exp2P","exp3P","power2P","power3P") 563 | if (!model %in% Check) 564 | stop(" 565 | \"model\" should be one of c(\"lin2P\",\"line3P\",\"log2P\",\"exp2P\",\"exp3P\",\"power2P\",\"power3P\".") 566 | } 567 | 568 | nrow = as.numeric(nrow) 569 | r2=as.numeric(r2) 570 | adjr2=as.numeric(adjr2) 571 | pval=as.numeric(pval) 572 | AIC = as.numeric(format(AIC(fit), digits = eDigit)) 573 | BIC = as.numeric(format(BIC(fit), digits = eDigit)) 574 | ss.res=as.numeric(format(ss.res, digits = eDigit)) 575 | 576 | logLik.fit <- stats::logLik(fit) 577 | logLik.fit <- logLik.fit[1] 578 | AICc = -2*logLik.fit+2*npar*(nrow/(nrow-npar-1)) 579 | AICc = as.numeric(format(AICc, digits = eDigit)) 580 | 581 | if (summary==TRUE){ 582 | ##print N, AIC, AICc, BIC and RSS 583 | cat("\nN:", nrow, ", AIC:", AIC, ", AICc:", AICc, ", BIC: ", BIC, "\nResidual Sum of Squares: ", ss.res,"\n") 584 | }else{} 585 | 586 | invisible(list(formula=formula, parameter=param.out, R.squared=r2, adj.R.squared=adjr2, p.value = pval, 587 | N = nrow, AIC=AIC, AICc=AICc, BIC=BIC, RSS=ss.res)) 588 | } 589 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ggtrendline: an R package for adding trendline and confidence interval to ggplot 2 | 3 | 4 | 5 | [![cran version](http://www.r-pkg.org/badges/version/ggtrendline)](http://cran.rstudio.com/web/packages/ggtrendline) 6 | [![rstudio mirror downloads](http://cranlogs.r-pkg.org/badges/grand-total/ggtrendline)](https://github.com/metacran/cranlogs.app) 7 | 8 | ## 1. Installing "ggtrendline" package in R 9 | 10 | - Get the released version from CRAN: 11 | 12 | install.packages("ggtrendline") 13 | 14 | - Or the development version from Github: 15 | 16 | install.packages("devtools") 17 | devtools::install_github("PhDMeiwp/ggtrendline@master", force = TRUE) 18 | library(ggtrendline) 19 | 20 | 21 | ## 2. Using "ggtrendline" package 22 | 23 | library(ggplot2) 24 | library(ggtrendline) 25 | x <- c(1, 3, 6, 9, 13, 17) 26 | y <- c(5, 8, 11, 13, 13.2, 13.5) 27 | 28 | ### 2.1 default ("line2P") 29 | 30 | ggtrendline(x, y, model = "line2P") 31 | 32 | 33 | 34 | 35 | 36 | 37 | ### 2.2 add geom_point() 38 | 39 | ggtrendline(x, y, model = "line3P") + geom_point(aes(x, y)) + theme_bw() 40 | 41 | 42 | 43 | ### 2.3 CI lines only, without CI filling 44 | 45 | ggtrendline(x, y, model = "log2P", CI.fill = NA) + 46 | geom_point(aes(x, y))+ theme_classic() 47 | 48 | 49 | 50 | ### 2.4 set the regression line and geom_point() 51 | 52 | ggtrendline(x, y, model = "exp2P", linecolor = "blue", linetype = 1, linewidth = 1) + 53 | geom_point(aes(x, y), color = "blue", shape = 1, size = 3) 54 | 55 | 56 | 57 | ### 2.5 set confidence interval 58 | 59 | ggtrendline(x, y, model = "exp3P", CI.level = 0.99, 60 | CI.fill = "red", CI.alpha = 0.1, CI.color = NA, CI.lty = 2, CI.lwd = 1.5) + 61 | geom_point(aes(x, y)) 62 | 63 | 64 | 65 | ### 2.6 one trendline with different points belonged to multiple groups. 66 | 67 | library(ggplot2) 68 | library(ggtrendline) 69 | data("iris") 70 | x <- iris$Petal.Width 71 | y <- iris$Petal.Length 72 | group <- iris$Species 73 | ggtrendline(x,y,"exp3P") + geom_point(aes(x,y,color=group)) 74 | 75 | 76 | 77 | ## 3. Details 78 | 79 | ### 3.1 Description 80 | 81 | The 'ggtrendline' package is developed for adding **trendline and confidence interval** of **linear or nonlinear regression** model, and 82 | **showing equation, R square, and P value** to 'ggplot' as simple as possible. 83 | 84 |
For a general overview of the methods used in this package, 85 | see Ritz and Streibig (2008) and 86 | Greenwell and Schubert Kabban (2014) . 87 | 88 | ### 3.2 ggtrendline function 89 | 90 | The built-in 'ggtrendline()' function includes the following models:
91 |
"line2P", formula as: y = a\*x + b; 92 |
"line3P", y = a\*x^2 + b\*x + c; 93 |
"log2P" , y = a\*ln(x) + b; 94 |
"exp2P", y = a\*exp(b\*x); 95 |
"exp3P", y = a\*exp(b\*x) + c; 96 |
"power2P", y = a\*x^b; 97 |
"power3P", y = a\*x^b + c. 98 | 99 | ### 3.3 stat_eq and stat_rrp functions 100 | 101 | **The built-in 'stat_eq()' and 'stat_rrp()' functions can be used separately, i.e., not together with 'ggtrendline()' function.** 102 | 103 | To see more details, you can run the following R code if you have the "ggtrendline" package installed: 104 | 105 | library(ggtrendline) 106 | ?ggtrendline 107 | ?stat_eq 108 | ?stat_rrp 109 | 110 | ## 4. Contact 111 | 112 | - Bugs and feature requests can be filed to https://github.com/PhDMeiwp/ggtrendline/issues. 113 | - BTW, [Pull requests](https://github.com/PhDMeiwp/ggtrendline/pulls) are also welcome. 114 | 115 | ## 5. Acknowledgements 116 | 117 | We would like to express our special thanks to **Uwe Ligges, Gregor Seyer, and CRAN team** for their valuable comments to the 'ggtrendline' package. 118 | -------------------------------------------------------------------------------- /ggtrendline.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /man/SSexp2P.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SSexp2P.R 3 | \name{SSexp2P} 4 | \alias{SSexp2P} 5 | \title{Self-Starting Nls 'exp2P' Regression Model} 6 | \usage{ 7 | SSexp2P(predictor, a, b) 8 | } 9 | \arguments{ 10 | \item{predictor}{a numeric vector of values at which to evaluate the model.} 11 | 12 | \item{a, b}{The numeric parameters responding to the exp2P model.} 13 | } 14 | \value{ 15 | No return value (called for side effects). 16 | } 17 | \description{ 18 | This selfStart model evaluates the power regression function (formula as: y=a*exp(b*x)). It has an initial attribute that will evaluate initial estimates of the parameters 'a' and 'b' for a given set of data. 19 | } 20 | \examples{ 21 | library(ggtrendline) 22 | x<-1:5 23 | y<-c(2,4,8,20,25) 24 | xy<-data.frame(x,y) 25 | getInitial(y ~ SSexp2P(x,a,b), data = xy) 26 | ## Initial values are in fact the converged values 27 | 28 | fitexp2P <- nls(y~SSexp2P(x,a,b), data=xy) 29 | summary(fitexp2P) 30 | 31 | prediction <- predFit(fitexp2P , data.frame(x=x), se.fit = TRUE, 32 | level = 0.95, interval = "confidence") 33 | yfitexp2P <- prediction$fit 34 | yfitexp2P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 35 | 36 | } 37 | \seealso{ 38 | \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 39 | } 40 | -------------------------------------------------------------------------------- /man/SSexp3P.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SSexp3P.R 3 | \name{SSexp3P} 4 | \alias{SSexp3P} 5 | \title{Self-Starting Nls 'exp3P' Regression Model} 6 | \usage{ 7 | SSexp3P(predictor, a, b, c) 8 | } 9 | \arguments{ 10 | \item{predictor}{a numeric vector of values at which to evaluate the model.} 11 | 12 | \item{a, b, c}{Three numeric parameters responding to the exp3P model.} 13 | } 14 | \value{ 15 | No return value (called for side effects). 16 | } 17 | \description{ 18 | This selfStart model evaluates the exponential regression function (formula as: y=a*exp(b*x)+c). It has an initial attribute that will evaluate initial estimates of the parameters a, b, and c for a given set of data. 19 | } 20 | \examples{ 21 | library(ggtrendline) 22 | x<-1:5 23 | y<-c(2,4,8,16,28) 24 | xy<-data.frame(x,y) 25 | getInitial(y ~ SSexp3P(x,a,b,c), data = xy) 26 | ## Initial values are in fact the converged values 27 | 28 | fitexp3P <- nls(y~SSexp3P(x,a,b,c), data=xy) 29 | summary(fitexp3P) 30 | 31 | prediction <- predFit(fitexp3P , data.frame(x=x), se.fit = TRUE, 32 | level = 0.95, interval = "confidence") 33 | yfitexp3P <- prediction$fit 34 | yfitexp3P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 35 | 36 | } 37 | \seealso{ 38 | \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 39 | } 40 | -------------------------------------------------------------------------------- /man/SSpower2P.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SSpower2P.R 3 | \name{SSpower2P} 4 | \alias{SSpower2P} 5 | \title{Self-Starting Nls 'power2P' Regression Model} 6 | \usage{ 7 | SSpower2P(predictor, a, b) 8 | } 9 | \arguments{ 10 | \item{predictor}{a numeric vector of values at which to evaluate the model.} 11 | 12 | \item{a, b}{The numeric parameters responding to the exp2P model.} 13 | } 14 | \value{ 15 | No return value (called for side effects). 16 | } 17 | \description{ 18 | This selfStart model evaluates the power regression function (formula as: y=a*x^b). It has an initial attribute that will evaluate initial estimates of the parameters 'a' and 'b' for a given set of data. 19 | } 20 | \examples{ 21 | library(ggtrendline) 22 | x<-1:5 23 | y<-c(2,4,8,20,25) 24 | xy<-data.frame(x,y) 25 | getInitial(y ~ SSpower2P(x,a,b), data = xy) 26 | ## Initial values are in fact the converged values 27 | 28 | fitpower2P <- nls(y~SSpower2P(x,a,b), data=xy) 29 | summary(fitpower2P) 30 | 31 | prediction <- predFit(fitpower2P , data.frame(x=x), se.fit = TRUE, 32 | level = 0.95, interval = "confidence") 33 | yfitpower2P <- prediction$fit 34 | yfitpower2P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 35 | 36 | } 37 | \seealso{ 38 | \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 39 | } 40 | -------------------------------------------------------------------------------- /man/SSpower3P.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/SSpower3P.R 3 | \name{SSpower3P} 4 | \alias{SSpower3P} 5 | \title{Self-Starting Nls 'power3P' Regression Model} 6 | \usage{ 7 | SSpower3P(predictor, a, b, c) 8 | } 9 | \arguments{ 10 | \item{predictor}{a numeric vector of values at which to evaluate the model.} 11 | 12 | \item{a, b, c}{Three numeric parameters responding to the exp3P model.} 13 | } 14 | \value{ 15 | No return value (called for side effects). 16 | } 17 | \description{ 18 | This selfStart model evaluates the power regression function (formula as: y=a*x^b+c). It has an initial attribute that will evaluate initial estimates of the parameters a, b, and c for a given set of data. 19 | } 20 | \examples{ 21 | library(ggtrendline) 22 | x<-1:5 23 | y<-c(2,4,8,20,25) 24 | xy<-data.frame(x,y) 25 | getInitial(y ~ SSpower3P(x,a,b,c), data = xy) 26 | ## Initial values are in fact the converged values 27 | 28 | fitpower3P <- nls(y~SSpower3P(x,a,b,c), data=xy) 29 | summary(fitpower3P) 30 | 31 | prediction <- predFit(fitpower3P , data.frame(x=x), se.fit = TRUE, 32 | level = 0.95, interval = "confidence") 33 | yfitpower3P <- prediction$fit 34 | yfitpower3P # output a matrix of predictions and bounds with column names fit, lwr, and upr. 35 | 36 | } 37 | \seealso{ 38 | \code{\link{ggtrendline}}, \code{\link{SSexp3P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 39 | } 40 | -------------------------------------------------------------------------------- /man/ggtrendline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggtrendline.R 3 | \name{ggtrendline} 4 | \alias{ggtrendline} 5 | \title{Add Trendline and Confidence Interval to 'ggplot'} 6 | \usage{ 7 | ggtrendline( 8 | x, 9 | y, 10 | model = "line2P", 11 | linecolor = "black", 12 | linetype = 1, 13 | linewidth = 0.6, 14 | CI.level = 0.95, 15 | CI.fill = "grey60", 16 | CI.alpha = 0.3, 17 | CI.color = "black", 18 | CI.lty = 2, 19 | CI.lwd = 0.5, 20 | summary = TRUE, 21 | show.eq = TRUE, 22 | yhat = FALSE, 23 | eq.x = NULL, 24 | eq.y = NULL, 25 | show.Rsquare = TRUE, 26 | show.pvalue = TRUE, 27 | Pvalue.corrected = TRUE, 28 | Rname = 0, 29 | Pname = 0, 30 | rrp.x = NULL, 31 | rrp.y = NULL, 32 | text.col = "black", 33 | eDigit = 3, 34 | eSize = 3, 35 | xlab = NULL, 36 | ylab = NULL 37 | ) 38 | } 39 | \arguments{ 40 | \item{x, y}{the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable.} 41 | 42 | \item{model}{select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c} 43 | 44 | \item{linecolor}{the color of regression line. Default is "black".} 45 | 46 | \item{linetype}{the type of regression line. Default is 1. Notes: linetype can be specified using either text c("blank","solid","dashed","dotted","dotdash","longdash","twodash") or number c(0, 1, 2, 3, 4, 5, 6).} 47 | 48 | \item{linewidth}{the width of regression line. Default is 0.6.} 49 | 50 | \item{CI.level}{level of confidence interval to use. Default is 0.95.} 51 | 52 | \item{CI.fill}{the color for filling the confidence interval. Default is "grey60".} 53 | 54 | \item{CI.alpha}{alpha value of filling color of confidence interval. Default is 0.3.} 55 | 56 | \item{CI.color}{line color of confidence interval. Default is "black".} 57 | 58 | \item{CI.lty}{line type of confidence interval. Default is 2.} 59 | 60 | \item{CI.lwd}{line width of confidence interval. Default is 0.5.} 61 | 62 | \item{summary}{summarizing the model fits. Default is TRUE.} 63 | 64 | \item{show.eq}{whether to show the regression equation, the value is one of c("TRUE", "FALSE").} 65 | 66 | \item{yhat}{whether to add a hat symbol (^) on the top of "y" in equation. Default is FALSE.} 67 | 68 | \item{eq.x, eq.y}{equation position.} 69 | 70 | \item{show.Rsquare}{whether to show the R-square, the value is one of c("TRUE", "FALSE").} 71 | 72 | \item{show.pvalue}{whether to show the P-value, the value is one of c("TRUE", "FALSE").} 73 | 74 | \item{Pvalue.corrected}{if P-value corrected or not, the value is one of c("TRUE", "FALSE").} 75 | 76 | \item{Rname}{to specify the character of R-square, the value is one of c(0, 1), corresponding to c(r^2, R^2).} 77 | 78 | \item{Pname}{to specify the character of P-value, the value is one of c(0, 1), corresponding to c(p, P).} 79 | 80 | \item{rrp.x, rrp.y}{the position for R square and P value.} 81 | 82 | \item{text.col}{the color used for the equation text.} 83 | 84 | \item{eDigit}{the numbers of digits for R square and P value. Default is 3.} 85 | 86 | \item{eSize}{font size of R square and P value. Default is 3.} 87 | 88 | \item{xlab, ylab}{labels of x- and y-axis.} 89 | } 90 | \value{ 91 | No return value (called for side effects). 92 | } 93 | \description{ 94 | Add trendline and confidence interval of linear or nonlinear regression model to 'ggplot', 95 | by using different models built in the 'ggtrendline()' function. \cr The function includes the following models:\cr 96 | "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 97 | } 98 | \details{ 99 | The values of each parameter of regression model can be found by typing \code{\link{trendline_sum}} function in this package.\cr\cr The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method). 100 | } 101 | \examples{ 102 | # library(ggplot2) 103 | library(ggtrendline) 104 | x <- c(1, 3, 6, 9, 13, 17) 105 | y <- c(5, 8, 11, 13, 13.2, 13.5) 106 | 107 | ggtrendline(x, y, model = "line2P") # default 108 | ggtrendline(x, y, model = "log2P", CI.fill = NA) # CI lines only, without CI filling 109 | 110 | ggtrendline(x, y, model = "exp2P", linecolor = "blue", linetype = 1, linewidth = 1) # set line 111 | ggtrendline(x, y, model = "exp3P", CI.level = 0.99, 112 | CI.fill = "red", CI.alpha = 0.1, CI.color = NA, CI.lty = 2, CI.lwd = 1.5) # set CI 113 | 114 | } 115 | \references{ 116 | Ritz C., and Streibig J. C. (2007) 117 | \emph{Nonlinear Regression with R}. Springer. 118 | 119 | Greenwell B. M., and Schubert Kabban C. M. (2014) 120 | \emph{investr: An R Package for Inverse Estimation}. The R Journal, 6(1), 90-100. 121 | } 122 | \seealso{ 123 | \code{\link{ggtrendline}}, \code{\link{stat_eq}}, \code{\link{stat_rrp}}, \code{\link{trendline_sum}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}} 124 | } 125 | -------------------------------------------------------------------------------- /man/predFit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/predFit.R 3 | \name{predFit} 4 | \alias{predFit} 5 | \alias{predFit.default} 6 | \alias{predFit.nls} 7 | \title{Predictions from a Fitted Model} 8 | \usage{ 9 | predFit(object, ...) 10 | 11 | \method{predFit}{default}(object, ...) 12 | 13 | \method{predFit}{nls}( 14 | object, 15 | newdata, 16 | se.fit = FALSE, 17 | interval = c("none", "confidence", "prediction"), 18 | level = 0.95, 19 | adjust = c("none", "Bonferroni", "Scheffe"), 20 | k, 21 | ... 22 | ) 23 | } 24 | \arguments{ 25 | \item{object}{An object that inherits from class \code{"lm"}, \code{"nls"}.} 26 | 27 | \item{...}{Additional optional arguments. At present, no optional arguments 28 | are used.} 29 | 30 | \item{newdata}{An optional data frame in which to look for variables with 31 | which to predict. If omitted, the fitted values are used.} 32 | 33 | \item{se.fit}{A logical vaue indicating if standard errors are required. 34 | Default is \code{FALSE}.} 35 | 36 | \item{interval}{Type of interval to be calculated. Can be one of "none" 37 | (default), "confidence", or "prediction". Default is \code{"none"}.} 38 | 39 | \item{level}{A numeric scalar between 0 and 1 giving the confidence level for 40 | the intervals (if any) to be calculated. Default is \code{0.95}.} 41 | 42 | \item{adjust}{A logical value indicating if an adjustment should be made to 43 | the critical value used in calculating the confidence interval. This is 44 | useful for when the calibration curve is to be used multiple, say k, times. 45 | Default is \code{FALSE}.} 46 | 47 | \item{k}{The number times the calibration curve is to be used for computing 48 | a confidence/prediction interval. Only needed when 49 | \code{adjust = "Bonferroni"}.} 50 | } 51 | \value{ 52 | No return value (called for side effects). 53 | } 54 | \description{ 55 | Generic prediction method for various types of fitted models. \code{predFit} 56 | can be used to obtain standard errors of fitted values and 57 | adjusted/unadjusted confidence/prediction intervals for objects of class 58 | \code{"lm"}, \code{"nls"}. 59 | } 60 | \note{ 61 | predFit function is from 'investr' package written by Brandon M. Greenwell. 62 | } 63 | \references{ 64 | Greenwell B. M., and Schubert-Kabban, C. M. (2014) 65 | \emph{investr: An R Package for Inverse Estimation}. The R Journal, 6(1), 90-100. 66 | } 67 | \seealso{ 68 | \code{\link[investr]{predFit}} 69 | } 70 | -------------------------------------------------------------------------------- /man/stat_eq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stat_eq.R 3 | \name{stat_eq} 4 | \alias{stat_eq} 5 | \title{Add Equation to 'ggplot'} 6 | \usage{ 7 | stat_eq( 8 | x, 9 | y, 10 | model = "line2P", 11 | show.eq = TRUE, 12 | xname = "x", 13 | yname = "y", 14 | yhat = FALSE, 15 | eq.x = NULL, 16 | eq.y = NULL, 17 | text.col = "black", 18 | eDigit = 3, 19 | eSize = 3 20 | ) 21 | } 22 | \arguments{ 23 | \item{x, y}{the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable.} 24 | 25 | \item{model}{select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c} 26 | 27 | \item{show.eq}{whether to show the regression equation, the value is one of c("TRUE", "FALSE").} 28 | 29 | \item{xname}{to specify the expression of "x" in equation, i.e., expression('x'), see Examples.} 30 | 31 | \item{yname}{to specify the expression of "y" in equation, i.e., expression('y'), see Examples.} 32 | 33 | \item{yhat}{whether to add a hat symbol (^) on the top of "y" in equation. Default is FALSE.} 34 | 35 | \item{eq.x, eq.y}{equation position.} 36 | 37 | \item{text.col}{the color used for the equation text.} 38 | 39 | \item{eDigit}{the numbers of digits for equation parameters. Default is 3.} 40 | 41 | \item{eSize}{font size of equation. Default is 3.} 42 | } 43 | \value{ 44 | No return value (called for side effects). 45 | } 46 | \description{ 47 | Add regression equation to 'ggplot', 48 | by using different models built in the 'ggtrendline()' function. The function includes the following models: \cr 49 | "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 50 | } 51 | \details{ 52 | The values of each parameter of regression model can be found by typing \code{\link{trendline_sum}} function in this package.\cr\cr The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method). 53 | } 54 | \seealso{ 55 | \code{\link{ggtrendline}}, \code{\link{stat_rrp}}, \code{\link{trendline_sum}} 56 | } 57 | -------------------------------------------------------------------------------- /man/stat_rrp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stat_rrp.R 3 | \name{stat_rrp} 4 | \alias{stat_rrp} 5 | \title{Add R square and P-value to 'ggplot'} 6 | \usage{ 7 | stat_rrp( 8 | x, 9 | y, 10 | model = "line2P", 11 | Pvalue.corrected = TRUE, 12 | show.Rsquare = TRUE, 13 | show.pvalue = TRUE, 14 | Rname = 0, 15 | Pname = 0, 16 | rrp.x = NULL, 17 | rrp.y = NULL, 18 | text.col = "black", 19 | eDigit = 3, 20 | eSize = 3 21 | ) 22 | } 23 | \arguments{ 24 | \item{x, y}{the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable.} 25 | 26 | \item{model}{select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c} 27 | 28 | \item{Pvalue.corrected}{if P-value corrected or not, the value is one of c("TRUE", "FALSE").} 29 | 30 | \item{show.Rsquare}{whether to show the R-square, the value is one of c("TRUE", "FALSE").} 31 | 32 | \item{show.pvalue}{whether to show the P-value, the value is one of c("TRUE", "FALSE").} 33 | 34 | \item{Rname}{to specify the character of R-square, the value is one of c(0, 1), corresponding to c(r^2, R^2).} 35 | 36 | \item{Pname}{to specify the character of P-value, the value is one of c(0, 1), corresponding to c(p, P).} 37 | 38 | \item{rrp.x, rrp.y}{the position for R square and P value.} 39 | 40 | \item{text.col}{the color used for the equation text.} 41 | 42 | \item{eDigit}{the numbers of digits for R square and P value. Default is 3.} 43 | 44 | \item{eSize}{font size of R square and P value. Default is 3.} 45 | } 46 | \value{ 47 | No return value (called for side effects). 48 | } 49 | \description{ 50 | Add R-square and P-value of regression models to 'ggplot', 51 | by using models built in the 'ggtrendline()' function. The function includes the following models: \cr 52 | "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 53 | } 54 | \details{ 55 | The values of each parameter of regression model can be found by typing \code{\link{trendline_sum}} function in this package.\cr\cr The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method).\cr\cr The argument 'Pvalue.corrected' is only valid for non-linear regression.\cr\cr If "Pvalue.corrected = TRUE", the P-value is calculated by using "Residual Sum of Squares" and "Corrected Total Sum of Squares (i.e. sum((y-mean(y))^2))".\cr\cr If "Pvalue.corrected = FALSE", the P-value is calculated by using "Residual Sum of Squares" and "Uncorrected Total Sum of Squares (i.e. sum(y^2))". 56 | } 57 | \seealso{ 58 | \code{\link{ggtrendline}}, \code{\link{stat_eq}}, \code{\link{trendline_sum}} 59 | } 60 | -------------------------------------------------------------------------------- /man/trendline_sum.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trendline_sum.R 3 | \name{trendline_sum} 4 | \alias{trendline_sum} 5 | \title{Summarized Results of Each Regression Model} 6 | \usage{ 7 | trendline_sum( 8 | x, 9 | y, 10 | model = "line2P", 11 | Pvalue.corrected = TRUE, 12 | summary = TRUE, 13 | eDigit = 5 14 | ) 15 | } 16 | \arguments{ 17 | \item{x, y}{the x and y arguments provide the x and y coordinates for the 'ggplot'. Any reasonable way of defining the coordinates is acceptable.} 18 | 19 | \item{model}{select which model to fit. Default is "line2P". The "model" should be one of c("line2P", "line3P", "log2P", "exp2P", "exp3P", "power2P", "power3P"), their formulas are as follows:\cr "line2P": y=a*x+b \cr "line3P": y=a*x^2+b*x+c \cr "log2P": y=a*ln(x)+b \cr "exp2P": y=a*exp(b*x) \cr "exp3P": y=a*exp(b*x)+c \cr "power2P": y=a*x^b \cr "power3P": y=a*x^b+c} 20 | 21 | \item{Pvalue.corrected}{if P-value corrected or not, the value is one of c("TRUE", "FALSE").} 22 | 23 | \item{summary}{summarizing the model fits. Default is TRUE.} 24 | 25 | \item{eDigit}{the numbers of digits for summarized results. Default is 3.} 26 | } 27 | \value{ 28 | R^2, indicates the R-Squared value of each regression model. 29 | 30 | p, indicates the p-value of each regression model. 31 | 32 | N, indicates the sample size. 33 | 34 | AIC, AICc, or BIC, indicate the Akaike's Information Criterion (AIC), the second-order AIC (AICc) for small samples, or Bayesian Information Criterion (BIC) for fitted model. Click \code{\link[stats]{AIC}} for details. The smaller the AIC, AICc or BIC, the better the model. 35 | 36 | RSS, indicate the value of "Residual Sum of Squares". 37 | } 38 | \description{ 39 | Summarizing the results of linear or nonlinear regression model which built in the 'ggtrendline()' function. The function includes the following models:\cr 40 | "line2P" (formula as: y=a*x+b), \cr "line3P" (y=a*x^2+b*x+c), \cr "log2P" (y=a*ln(x)+b), \cr "exp2P" (y=a*exp(b*x)), \cr "exp3P" (y=a*exp(b*x)+c), \cr "power2P" (y=a*x^b), \cr and "power3P" (y=a*x^b+c). 41 | } 42 | \details{ 43 | The linear models (line2P, line3P, log2P) in this package are estimated by \code{\link[stats]{lm}} function, \cr while the nonlinear models (exp2P, exp3P, power2P, power3P) are estimated by \code{\link[stats]{nls}} function (i.e., least-squares method).\cr\cr The argument 'Pvalue.corrected' is workful for non-linear regression only.\cr\cr If "Pvalue.corrected = TRUE", the P-vlaue is calculated by using "Residual Sum of Squares" and "Corrected Total Sum of Squares (i.e. sum((y-mean(y))^2))".\cr\cr If "Pvalue.corrected = TRUE", the P-vlaue is calculated by using "Residual Sum of Squares" and "Uncorrected Total Sum of Squares (i.e. sum(y^2))". 44 | } 45 | \note{ 46 | If the output of 'AICc' is 'Inf', not an exact number, please try to expand the sample size of your dataset to >=6. 47 | } 48 | \examples{ 49 | library(ggtrendline) 50 | x <- c(1, 3, 6, 9, 13, 17) 51 | y <- c(5, 8, 11, 13, 13.2, 13.5) 52 | 53 | trendline_sum(x, y, model="exp3P", summary=TRUE, eDigit=3) 54 | 55 | } 56 | \seealso{ 57 | \code{\link{ggtrendline}}, \code{\link{SSexp2P}}, \code{\link{SSexp3P}}, \code{\link{SSpower2P}}, \code{\link{SSpower3P}}, \code{\link[stats]{nls}}, \code{\link[stats]{selfStart}}, \code{\link[AICcmodavg]{AICc}} 58 | } 59 | --------------------------------------------------------------------------------