diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..8f61fb7 Binary files /dev/null and b/.DS_Store differ diff --git a/.RData b/.RData new file mode 100644 index 0000000..72fd143 Binary files /dev/null and b/.RData differ diff --git a/.gitignore b/.gitignore index 8c1d3af..b390bea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .Rhistory test.R .lintr -*.gz \ No newline at end of file +*.gz +.Rproj.user diff --git a/ProbDistCalc_RShiny.Rproj b/ProbDistCalc_RShiny.Rproj new file mode 100644 index 0000000..8e3c2eb --- /dev/null +++ b/ProbDistCalc_RShiny.Rproj @@ -0,0 +1,13 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX diff --git a/distribution_info.yaml b/distribution_info.yaml index 05bbe65..9f09314 100644 --- a/distribution_info.yaml +++ b/distribution_info.yaml @@ -216,9 +216,15 @@ Chi Square Non Central Distribution: Circle Distribution: id: 15 name: Circle - inputNames: CircleRadius - labels: radius - defaultValues: 2.0 + inputNames: + - CircleRadius + - CircleCenter + labels: + - radius + - center + defaultValues: + - 2.0 + - 0.0 hasImplementation: yes isWithSD: no fitFunc: fitCircle diff --git a/fitFunctions.R b/fitFunctions.R index 07c4f22..64816d2 100644 --- a/fitFunctions.R +++ b/fitFunctions.R @@ -1,27 +1,52 @@ -# FIXME: This is not working -# fitAndersonDarling <- function(dataset) { -# fitDistModel <- fitdist(dataset, "andersonDarling") -# return(fitDistModel) -# } -# FIXME: This is not working -# fitArcSine <- function(dataset) { -# fitDistModel <- fitdist(dataset, "arcsine") -# return(fitDistModel) -# } - -# FIXME: This is not working -# fitBenford <- function(dataset) { -# rounded_data <- round(dataset) -# fitDistModel <- fitdist(rounded_data, "benford") -# return(fitDistModel) -# } + fitAndersonDarling <- function(dataset) { + fitDistModel <- fitdist(dataset, "andersonDarling") + return(fitDistModel) + } + + +fitArcSine <- function(dataset) { + dataset_scaled <- (dataset - min(dataset)) / (max(dataset) - min(dataset)) + dcustom <- function(x, a, b) { + ifelse(x > a & x < b, 1 / (pi * sqrt((x - a) * (b - x))), 0) + } + + pcustom <- function(q, a, b) { + if (q > a & q < b) { + return(asin(sqrt((q - a) / (b - a))) / (pi / 2)) + } else if (q <= a) { + return(0) + } else { + return(1) + } + } + + qcustom <- function(p, a, b) { + if (p >= 0 & p <= 1) { + return(a + (b - a) * sin((pi / 2) * p)^2) + } else if (p < 0) { + return(a) + } else { + return(b) + } + } + fitDistModel <- fitdist( dataset_scaled, "custom", method = "mle", start = list(a = 0, b = 1)) + return(fitDistModel) + } + +fitBenford <- function(dataset) { + single_cell_table <- data.frame("estimate" = 1) + row.names(single_cell_table) <- "Benfn" + + return(single_cell_table) +} + +fitBernoulli <- function(dataset) { + + p_hat <- mean(dataset) + return(list(estimate = p_hat)) +} -# FIXME: This is not working -# fitBernoulli <- function(dataset) { -# fitDistModel <- fitdist(dataset, "bernoulli") -# return(fitDistModel) -# } fitBeta <- function(dataset) { @@ -43,6 +68,42 @@ fitBeta <- function(dataset) { # return(fitDistModel) # } + +library(extraDistr) +library(bbmle) + # Round to nearest integer + +fitBetaBinomial <- function(dataset) { + dataset <- round(dataset) + size <- ceiling(max(dataset)) + + # Define the negative log-likelihood function for Beta-Binomial + neg_log_likelihood <- function(alpha, beta) { + if (alpha <= 0 || beta <= 0) return(Inf) + -sum(dbbinom(dataset, size = size, alpha = alpha, beta = beta, log = TRUE)) + } + + # Fit the model using MLE + fit <- mle2( + neg_log_likelihood, + start = list(alpha = 1, beta = 1), + method = "L-BFGS-B", + lower = c(0.0001, 0.0001), + control = list(maxit = 1000) + ) + fit_df <- data.frame( + estimate = c( size,coef(fit)["alpha"], coef(fit)["beta"]), + row.names = c( "n", "alpha", "beta") + ) + + return(fit_df) +} + + + + + + # FIXME: This is not working # fitBinomial <- function(dataset) { # rounded_data <- round(dataset) @@ -85,11 +146,38 @@ fitCauchy <- function(dataset) { # return(fitDistModel) # } -# FIXME: This is not working -# fitCircle <- function(dataset) { -# fitDistModel <- fitdist(dataset, "circle") -# return(fitDistModel) -# } +library(minpack.lm) + +fitCircle <- function(dataset) { + # Define residual function to minimize + circleResiduals <- function(params) { + r <- params[1] # radius of the circle + c <- params[2] # center of the circle + abs(dataset - c) - r # residuals: difference from each point to radius centered at c + } + + # Provide initial guesses for radius and center + start_center <- mean(dataset) # initial guess for center + start_radius <- max(abs(dataset - start_center)) # initial guess for radius + + # Fit radius and center using nonlinear least squares + fitResult <- nls.lm(par = c(start_radius, start_center), fn = circleResiduals, control = list(maxiter = 100)) + + # Extract the fitted radius and center + fitted_radius <- fitResult$par[1] + fitted_center <- fitResult$par[2] + + + # Return a data frame with one row and one column containing the fitted radius + fit_df <- data.frame( + estimate = c( fitted_radius, fitted_center), + row.names = c( "radius", "center") + ) + return(fit_df) + + + + } # Not tested fitContinuousUniform <- function(dataset) { @@ -97,28 +185,194 @@ fitContinuousUniform <- function(dataset) { return(fitDistModel) } -# Not tested +coupon_likelihood <- function(params, data) { + N <- params[1] # Total population size (number of distinct items) + k <- params[2] # Number of distinct items needed + + # Calculate expected trials based on harmonic sum approximation + expected_trials <- N * sum(1 / (N - (0:(k - 1)))) + + # Round data to integer values for Poisson + rounded_data <- round(data) + + # Calculate the negative log-likelihood using the rounded data + -sum(dpois(rounded_data, lambda = expected_trials, log = TRUE)) +} +# Not tested +coupon_likelihood <- function(params, data) { + N <- params[1] # Total population size (number of distinct items) + k <- params[2] # Number of distinct items needed + + # Calculate expected trials based on harmonic sum approximation + expected_trials <- N * sum(1 / (N - (0:(k - 1)))) + + # Round data to integer values for Poisson + rounded_data <- round(data) + + # Calculate the negative log-likelihood using the rounded data + -sum(dpois(rounded_data, lambda = expected_trials, log = TRUE)) +} fitCoupon <- function(dataset) { - fitDistModel <- fitdist(dataset, "coupon") - return(fitDistModel) + # Initial guesses for N and k + start_params <- c(N = max(dataset), k = round(mean(dataset) / 2)) + + # Perform optimization with integer constraint on k + fit_result <- optim( + par = start_params, + fn = coupon_likelihood, + data = dataset, + method = "L-BFGS-B", + lower = c(1, 1), + upper = c(Inf, Inf) + ) + + # Extract fitted parameters, rounding k to the nearest integer + N_estimate <- round(fit_result$par[1]) + k_estimate <- round(fit_result$par[2]) # Ensure integer k + + # Return the results as a data frame + fit_df <- data.frame( + estimate = c(N_estimate, k_estimate), + row.names = c("Population Size", "Number of distinct values needed") + ) + + return(fit_df) } # Not tested fitDie <- function(dataset) { - fitDistModel <- fitdist(dataset, "die") - return(fitDistModel) + getDensity_Die <- function(x) { + k <- round(x) + if (n_Die == 0) { + # FAIR Die + if (k < 1 || k > 6) { + return(0) + } else { + return(1/6) + } + } else if (n_Die == 1) { + # FLAT16 Die + if (k < 1 || k > 6) { + return(0) + } else if (k == 1 || k == 6) { + return(1/4) + } else { + return(1/8) + } + } else if (n_Die == 2) { + # FLAT25 Die + if (k < 1 || k > 6) { + return(0) + } else if (k == 2 || k == 5) { + return(1/4) + } else { + return(1/8) + } + } else if (n_Die == 3) { + # FLAT34 Die + if (k < 1 || k > 6) { + return(0) + } else if (k == 3 || k == 4) { + return(1/4) + } else { + return(1/8) + } + } else if (n_Die == 4) { + # LEFT Die + if (k < 1 || k > 6) { + return(0) + } else if (k == 1) { + return(1/21) + } else if (k == 2) { + return(2/21) + } else if (k == 3) { + return(3/21) + } else if (k == 4) { + return(4/21) + } else if (k == 5) { + return(5/21) + } else { + return(6/21) + } + } else if (n_Die == 5) { + # RIGHT Die + if (k < 1 || k > 6) { + return(0) + } else if (k == 1) { + return(6/21) + } else if (k == 2) { + return(5/21) + } else if (k == 3) { + return(4/21) + } else if (k == 4) { + return(3/21) + } else if (k == 5) { + return(2/21) + } else { + return(1/21) + } + } + } + best_die_type <- NULL + lowest_residual <- Inf + residuals_list <- list() + + + for (die_type in 0:5) { + n_Die <<- die_type + expected_density <- sapply(dataset, getDensity_Die) + residuals <- (1 / length(dataset) - expected_density)^2 + residual_sum <- sum(residuals) + residuals_list[[paste0("Die_Type_", die_type)]] <- residual_sum + + if (residual_sum < lowest_residual) { + lowest_residual <- residual_sum + best_die_type <- die_type + } + } + fit_df <- data.frame( + estimate = best_die_type, + row.names = 'n (0 <= n <= 5)' + ) + return(fit_df) } # Not tested fitDiscreteArcSine <- function(dataset) { - fitDistModel <- fitdist(dataset, "disarc") + dataset <- round(dataset) + darcsine <- function(x, a, b) { + if (a >= b) stop("Invalid range: a must be less than b") + ifelse(x >= a & x <= b, 1 / (pi * sqrt((x - a) * (b - x))), 0) + } + + # CDF of the arcsine distribution + parcsine <- function(q, a, b) { + if (a >= b) stop("Invalid range: a must be less than b") + ifelse( + q < a, 0, + ifelse( + q > b, 1, + (2 / pi) * asin(sqrt((q - a) / (b - a))) + ) + ) + } + + # Quantile function (inverse CDF) of the arcsine distribution + qarcsine <- function(p, a, b) { + if (a >= b) stop("Invalid range: a must be less than b") + if (p < 0 | p > 1) stop("Probability p must be in [0, 1]") + a + (b - a) * sin((p * pi) / 2)^2 + } + + fitDistModel <- fitdist( dataset, "arcsine", method = "mle", start = list(a = 1, b = 2)) return(fitDistModel) } # Not tested fitDiscreteUniform <- function(dataset) { - rounded_data <- round(dataset) - fitDistModel <- fitdist(rounded_data, "discunif") + #rounded_data <- round(dataset) + fitDistModel <-fitdist(dataset, "unif", method = c("mme"), + start=NULL, fix.arg=NULL, discrete = TRUE) return(fitDistModel) } @@ -128,6 +382,23 @@ fitDiscreteUniform <- function(dataset) { # return(fitDistModel) # } +fitErlang <- function(dataset) { + mean_data <- mean(dataset) + var_data <- var(dataset) + + # Rough estimate of the shape parameter + myshape <- round(mean_data^2/var_data) + + + fit_df <- data.frame( + estimate = c( mean_data/myshape, myshape), + row.names = c( "scale", "shape") + ) + return(fit_df) + +} + + # FIXME: This is not working # fitError <- function(dataset) { # fitDistModel <- fitdist(dataset, "error") diff --git a/plotlyFunctions/Circle.R b/plotlyFunctions/Circle.R index 9df32bf..82dea4d 100644 --- a/plotlyFunctions/Circle.R +++ b/plotlyFunctions/Circle.R @@ -1,68 +1,69 @@ -dCircle <- function(x, radius) { - ifelse((-radius <= x & x <= radius), (2 * sqrt(radius * radius - x * x) / (pi * radius * radius)), 0) +dCircle <- function(x, radius, center) { + ifelse((-radius + center <= x & x <= radius + center), + (2 * sqrt(radius * radius - (x - center) * (x - center)) / (pi * radius * radius)), + 0) } -pCircle <- function(x, radius) { - 0.5 + asin(x / radius) / pi + x * sqrt(1 - x * x / (radius * radius)) / (pi * radius) +pCircle <- function(x, radius, center) { + adjusted_x <- x - center + 0.5 + asin(adjusted_x / radius) / pi + adjusted_x * sqrt(1 - adjusted_x * adjusted_x / (radius * radius)) / (pi * radius) } -plotlyCircleDistribution <- function(plotrange, input, distType, probrange) { - xseq <- seq( - min(0, as.numeric(plotrange[1])), max(as.numeric(plotrange[2]), 10), - 0.01 - ) - f15 <- 0 - if (input$FunctionType == "PDF/PMF") { - f15 <- dCircle(xseq, as.numeric(input$CircleRadius)) - graphtype <- "PMF" - } else if (input$FunctionType == "CDF/CMF") { - f15 <- pCircle(xseq, as.numeric(input$CircleRadius)) - graphtype <- "CMF" - } else { - graphtype <- "" +plotlyCircleDistribution <- function(plotrange, input, distType, probrange, center) { + xseq <- seq( + min(0, as.numeric(plotrange[1])), max(as.numeric(plotrange[2]), 10), + 0.01 + ) + f15 <- 0 + if (input$FunctionType == "PDF/PMF") { + f15 <- dCircle(xseq, as.numeric(input$CircleRadius), as.numeric(input$CircleCenter)) + graphtype <- "PMF" + } else if (input$FunctionType == "CDF/CMF") { + f15 <- pCircle(xseq, as.numeric(input$CircleRadius), as.numeric(input$CircleCenter)) + graphtype <- "CMF" + } else { + graphtype <- "" + } + if (graphtype != "") { + xsize <- length(xseq) + colors <- c(rep("rgb(31, 119, 180)", xsize)) + for (index in 1:xsize) { + if (xseq[index] >= round(probrange[1], 0) && xseq[index] <= round(probrange[2], 0)) { + colors[index] <- "rgb(255, 127, 14)" + } } - if (graphtype != "") { - xsize <- length(xseq) - colors <- c(rep("rgb(31, 119, 180)", xsize)) - for (index in 1:xsize) { - if (xseq[index] >= round(probrange[1], 0) && xseq[index] <= round( - probrange[2], - 0 - )) { - colors[index] <- "rgb(255, 127, 14)" - } - } - - prob <- pCircle(as.numeric(probrange[2]), as.numeric(input$CircleRadius)) - pCircle(as.numeric(probrange[1]), as.numeric(input$CircleRadius)) - - fig <- plot_ly( - x = xseq, y = f15, name = distType, type = "scatter", mode = "lines", - hoverinfo = "xy" - ) - - fig <- fig %>% - add_trace( - x = xseq, y = f15, name = paste("Probability = ", prob, sep = ""), - hoverinfo = "name", fill = "tozeroy", fillcolor = "rgba(255, 212, 96, 0.5)" - ) - fig <- fig %>% - plotly::layout( - title = paste(distributions[15], " - ", graphtype, sep = ""), - hovermode = "x", hoverlabel = list(namelength = 100), yaxis = list( - fixedrange = TRUE, - zeroline = TRUE, range = c(min(f15), max(f15)), type = "linear" - ), - xaxis = list( - showticklabels = TRUE, title = "* All x values rounded to nearest integers", - zeroline = TRUE, showline = TRUE, showgrid = TRUE, linecolor = "rgb(204, 204, 204)", - linewidth = 2, mirror = TRUE, fixedrange = TRUE, range = c( - plotrange[1], - plotrange[2] - ) - ), showlegend = FALSE - ) - fig <- fig %>% - config(editable = FALSE) - fig - } -} + + prob <- pCircle(as.numeric(probrange[2]), as.numeric(input$CircleRadius), as.numeric(input$CircleCenter)) - + pCircle(as.numeric(probrange[1]), as.numeric(input$CircleRadius), as.numeric(input$CircleCenter)) + + fig <- plot_ly( + x = xseq, y = f15, name = distType, type = "scatter", mode = "lines", + hoverinfo = "xy" + ) + + fig <- fig %>% + add_trace( + x = xseq, y = f15, name = paste("Probability = ", prob, sep = ""), + hoverinfo = "name", fill = "tozeroy", fillcolor = "rgba(255, 212, 96, 0.5)" + ) + fig <- fig %>% + plotly::layout( + title = paste(distributions[15], " - ", graphtype, sep = ""), + hovermode = "x", hoverlabel = list(namelength = 100), yaxis = list( + fixedrange = TRUE, + zeroline = TRUE, range = c(min(f15), max(f15)), type = "linear" + ), + xaxis = list( + showticklabels = TRUE, title = "* All x values rounded to nearest integers", + zeroline = TRUE, showline = TRUE, showgrid = TRUE, linecolor = "rgb(204, 204, 204)", + linewidth = 2, mirror = TRUE, fixedrange = TRUE, range = c( + plotrange[1], + plotrange[2] + ) + ), showlegend = FALSE + ) + fig <- fig %>% + config(editable = FALSE) + fig + } +} \ No newline at end of file diff --git a/renv.lock b/renv.lock index 7d826f2..8fe6c3b 100644 --- a/renv.lock +++ b/renv.lock @@ -11,14 +11,12 @@ "Packages": { "BH": { "Package": "BH", - "Version": "1.81.0-1", "Source": "Repository", "Repository": "CRAN", "Hash": "68122010f01c4dcfbe58ce7112f2433d" }, "BayesTools": { "Package": "BayesTools", - "Version": "0.2.16", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -37,7 +35,6 @@ }, "Brobdingnag": { "Package": "Brobdingnag", - "Version": "1.2-9", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -49,7 +46,6 @@ }, "DT": { "Package": "DT", - "Version": "0.30", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -66,7 +62,6 @@ }, "DescTools": { "Package": "DescTools", - "Version": "0.99.50", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -95,7 +90,6 @@ }, "EigenR": { "Package": "EigenR", - "Version": "1.2.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -106,7 +100,6 @@ }, "Exact": { "Package": "Exact", - "Version": "3.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -120,7 +113,6 @@ }, "ExtDist": { "Package": "ExtDist", - "Version": "0.7-2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -131,7 +123,6 @@ }, "HypergeoMat": { "Package": "HypergeoMat", - "Version": "4.0.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -145,14 +136,12 @@ }, "JuliaConnectoR": { "Package": "JuliaConnectoR", - "Version": "1.1.1", "Source": "Repository", "Repository": "CRAN", "Hash": "68962adf163c6be3674eb6128b7b74a0" }, "MASS": { "Package": "MASS", - "Version": "7.3-60", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -167,7 +156,6 @@ }, "Matrix": { "Package": "Matrix", - "Version": "1.6-0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -184,7 +172,6 @@ }, "R6": { "Package": "R6", - "Version": "2.5.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -194,7 +181,6 @@ }, "RColorBrewer": { "Package": "RColorBrewer", - "Version": "1.1-3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -204,7 +190,6 @@ }, "Rcpp": { "Package": "Rcpp", - "Version": "1.0.11", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -215,7 +200,6 @@ }, "RcppArmadillo": { "Package": "RcppArmadillo", - "Version": "0.12.6.4.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -229,7 +213,6 @@ }, "RcppEigen": { "Package": "RcppEigen", - "Version": "0.3.3.9.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -242,7 +225,6 @@ }, "Rdpack": { "Package": "Rdpack", - "Version": "2.5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -256,7 +238,6 @@ }, "Rlab": { "Package": "Rlab", - "Version": "4.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -268,7 +249,6 @@ }, "VGAM": { "Package": "VGAM", - "Version": "1.1-9", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -282,7 +262,6 @@ }, "VaRES": { "Package": "VaRES", - "Version": "1.0.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -292,7 +271,6 @@ }, "anytime": { "Package": "anytime", - "Version": "0.3.9", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -304,7 +282,6 @@ }, "askpass": { "Package": "askpass", - "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -314,7 +291,6 @@ }, "assertthat": { "Package": "assertthat", - "Version": "0.2.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -324,7 +300,6 @@ }, "base64enc": { "Package": "base64enc", - "Version": "0.1-3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -334,7 +309,6 @@ }, "bbmle": { "Package": "bbmle", - "Version": "1.0.25", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -353,7 +327,6 @@ }, "bdsmatrix": { "Package": "bdsmatrix", - "Version": "1.3-6", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -364,7 +337,6 @@ }, "boot": { "Package": "boot", - "Version": "1.3-28.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -376,7 +348,6 @@ }, "bridgesampling": { "Package": "bridgesampling", - "Version": "1.1-2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -395,14 +366,12 @@ }, "brio": { "Package": "brio", - "Version": "1.1.3", "Source": "Repository", "Repository": "RSPM", "Hash": "976cf154dfb043c012d87cddd8bca363" }, "bslib": { "Package": "bslib", - "Version": "0.5.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -422,7 +391,6 @@ }, "ca": { "Package": "ca", - "Version": "0.71.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -432,7 +400,6 @@ }, "cachem": { "Package": "cachem", - "Version": "1.0.8", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -443,7 +410,6 @@ }, "callr": { "Package": "callr", - "Version": "3.7.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -456,7 +422,6 @@ }, "cellranger": { "Package": "cellranger", - "Version": "1.1.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -468,14 +433,12 @@ }, "chi": { "Package": "chi", - "Version": "0.1", "Source": "Repository", "Repository": "RSPM", "Hash": "a3d767e4e25d33afab7d7d406ed58def" }, "circular": { "Package": "circular", - "Version": "0.5-0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -488,7 +451,6 @@ }, "class": { "Package": "class", - "Version": "7.3-22", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -501,7 +463,6 @@ }, "cli": { "Package": "cli", - "Version": "3.6.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -512,7 +473,6 @@ }, "coda": { "Package": "coda", - "Version": "0.19-4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -523,7 +483,6 @@ }, "colorspace": { "Package": "colorspace", - "Version": "2.1-0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -537,14 +496,12 @@ }, "commonmark": { "Package": "commonmark", - "Version": "1.9.0", "Source": "Repository", "Repository": "CRAN", "Hash": "d691c61bff84bd63c383874d2d0c3307" }, "cpp11": { "Package": "cpp11", - "Version": "0.4.6", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -554,7 +511,6 @@ }, "crayon": { "Package": "crayon", - "Version": "1.5.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -566,7 +522,6 @@ }, "crosstalk": { "Package": "crosstalk", - "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -579,7 +534,6 @@ }, "curl": { "Package": "curl", - "Version": "5.1.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -589,7 +543,6 @@ }, "data.table": { "Package": "data.table", - "Version": "1.14.8", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -600,7 +553,6 @@ }, "deSolve": { "Package": "deSolve", - "Version": "1.38", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -614,7 +566,6 @@ }, "desc": { "Package": "desc", - "Version": "1.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -628,7 +579,6 @@ }, "diffobj": { "Package": "diffobj", - "Version": "0.3.5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -643,7 +593,6 @@ }, "digest": { "Package": "digest", - "Version": "0.6.33", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -654,7 +603,6 @@ }, "dplyr": { "Package": "dplyr", - "Version": "1.1.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -677,7 +625,6 @@ }, "e1071": { "Package": "e1071", - "Version": "1.7-13", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -693,7 +640,6 @@ }, "ellipsis": { "Package": "ellipsis", - "Version": "0.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -704,7 +650,6 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.22", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -715,7 +660,6 @@ }, "evd": { "Package": "evd", - "Version": "2.3-6.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -727,7 +671,6 @@ }, "expm": { "Package": "expm", - "Version": "0.999-7", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -738,7 +681,6 @@ }, "extraDistr": { "Package": "extraDistr", - "Version": "1.9.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -749,7 +691,6 @@ }, "fansi": { "Package": "fansi", - "Version": "1.0.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -761,14 +702,12 @@ }, "farver": { "Package": "farver", - "Version": "2.1.1", "Source": "Repository", "Repository": "CRAN", "Hash": "8106d78941f34855c440ddb946b8f7a5" }, "fastGHQuad": { "Package": "fastGHQuad", - "Version": "1.0.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -778,14 +717,12 @@ }, "fastmap": { "Package": "fastmap", - "Version": "1.1.1", "Source": "Repository", "Repository": "CRAN", "Hash": "f7736a18de97dea803bde0a2daaafb27" }, "fitdistrplus": { "Package": "fitdistrplus", - "Version": "1.1-11", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -800,7 +737,6 @@ }, "flexsurv": { "Package": "flexsurv", - "Version": "2.2.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -831,7 +767,6 @@ }, "fontawesome": { "Package": "fontawesome", - "Version": "0.5.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -843,7 +778,6 @@ }, "fs": { "Package": "fs", - "Version": "1.6.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -854,7 +788,6 @@ }, "generics": { "Package": "generics", - "Version": "0.1.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -865,7 +798,6 @@ }, "ggplot2": { "Package": "ggplot2", - "Version": "3.4.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -890,7 +822,6 @@ }, "gld": { "Package": "gld", - "Version": "2.6.6", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -903,7 +834,6 @@ }, "glue": { "Package": "glue", - "Version": "1.6.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -914,7 +844,6 @@ }, "gnm": { "Package": "gnm", - "Version": "1.1-5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -934,7 +863,6 @@ }, "gsl": { "Package": "gsl", - "Version": "2.1-8", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -944,7 +872,6 @@ }, "gtable": { "Package": "gtable", - "Version": "0.3.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -959,7 +886,6 @@ }, "here": { "Package": "here", - "Version": "1.0.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -969,7 +895,6 @@ }, "highr": { "Package": "highr", - "Version": "0.10", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -980,7 +905,6 @@ }, "hms": { "Package": "hms", - "Version": "1.1.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -994,7 +918,6 @@ }, "htmltools": { "Package": "htmltools", - "Version": "0.5.6.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1011,7 +934,6 @@ }, "htmlwidgets": { "Package": "htmlwidgets", - "Version": "1.6.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1026,7 +948,6 @@ }, "httpuv": { "Package": "httpuv", - "Version": "1.6.11", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1041,7 +962,6 @@ }, "httr": { "Package": "httr", - "Version": "1.4.7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1056,7 +976,6 @@ }, "isoband": { "Package": "isoband", - "Version": "0.2.7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1067,7 +986,6 @@ }, "jquerylib": { "Package": "jquerylib", - "Version": "0.1.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1077,7 +995,6 @@ }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1087,7 +1004,6 @@ }, "knitr": { "Package": "knitr", - "Version": "1.44", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1103,7 +1019,6 @@ }, "labeling": { "Package": "labeling", - "Version": "0.4.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1114,7 +1029,6 @@ }, "later": { "Package": "later", - "Version": "1.3.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1125,7 +1039,6 @@ }, "lattice": { "Package": "lattice", - "Version": "0.21-9", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1140,7 +1053,6 @@ }, "lazyeval": { "Package": "lazyeval", - "Version": "0.2.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1150,7 +1062,6 @@ }, "lifecycle": { "Package": "lifecycle", - "Version": "1.0.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1163,7 +1074,6 @@ }, "lmom": { "Package": "lmom", - "Version": "3.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1175,7 +1085,6 @@ }, "lmtest": { "Package": "lmtest", - "Version": "0.9-40", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1188,7 +1097,6 @@ }, "magrittr": { "Package": "magrittr", - "Version": "2.0.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1198,7 +1106,6 @@ }, "memoise": { "Package": "memoise", - "Version": "2.0.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1209,7 +1116,6 @@ }, "mgcv": { "Package": "mgcv", - "Version": "1.9-0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1226,7 +1132,6 @@ }, "mime": { "Package": "mime", - "Version": "0.12", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1236,7 +1141,6 @@ }, "mnormt": { "Package": "mnormt", - "Version": "2.1.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1246,7 +1150,6 @@ }, "mstate": { "Package": "mstate", - "Version": "0.3.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1261,7 +1164,6 @@ }, "muhaz": { "Package": "muhaz", - "Version": "1.2.6.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1272,7 +1174,6 @@ }, "munsell": { "Package": "munsell", - "Version": "0.5.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1283,7 +1184,6 @@ }, "mvtnorm": { "Package": "mvtnorm", - "Version": "1.2-3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1294,7 +1194,6 @@ }, "nlme": { "Package": "nlme", - "Version": "3.1-162", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1308,7 +1207,6 @@ }, "nloptr": { "Package": "nloptr", - "Version": "2.0.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1318,7 +1216,6 @@ }, "nnet": { "Package": "nnet", - "Version": "7.3-19", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1330,7 +1227,6 @@ }, "numDeriv": { "Package": "numDeriv", - "Version": "2016.8-1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1340,7 +1236,6 @@ }, "openssl": { "Package": "openssl", - "Version": "2.1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1350,7 +1245,6 @@ }, "optimx": { "Package": "optimx", - "Version": "2023-8.13", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1362,7 +1256,6 @@ }, "pillar": { "Package": "pillar", - "Version": "1.9.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1379,7 +1272,6 @@ }, "pkgbuild": { "Package": "pkgbuild", - "Version": "1.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1397,7 +1289,6 @@ }, "pkgconfig": { "Package": "pkgconfig", - "Version": "2.0.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1407,7 +1298,6 @@ }, "pkgload": { "Package": "pkgload", - "Version": "1.3.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1428,7 +1318,6 @@ }, "plotly": { "Package": "plotly", - "Version": "4.10.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1460,7 +1349,6 @@ }, "pracma": { "Package": "pracma", - "Version": "2.4.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1474,14 +1362,12 @@ }, "praise": { "Package": "praise", - "Version": "1.0.0", "Source": "Repository", "Repository": "RSPM", "Hash": "a555924add98c99d2f411e37e7d25e9f" }, "prettyunits": { "Package": "prettyunits", - "Version": "1.2.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1491,7 +1377,6 @@ }, "processx": { "Package": "processx", - "Version": "3.8.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1504,7 +1389,6 @@ }, "progress": { "Package": "progress", - "Version": "1.2.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1517,7 +1401,6 @@ }, "promises": { "Package": "promises", - "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1533,7 +1416,6 @@ }, "proxy": { "Package": "proxy", - "Version": "0.4-27", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1545,7 +1427,6 @@ }, "ps": { "Package": "ps", - "Version": "1.7.5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1556,7 +1437,6 @@ }, "purrr": { "Package": "purrr", - "Version": "1.0.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1571,7 +1451,6 @@ }, "quadprog": { "Package": "quadprog", - "Version": "1.5-8", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1581,14 +1460,12 @@ }, "qvcalc": { "Package": "qvcalc", - "Version": "1.0.3", "Source": "Repository", "Repository": "RSPM", "Hash": "2e083617d18360370d11d20be05bc715" }, "rappdirs": { "Package": "rappdirs", - "Version": "0.3.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1598,7 +1475,6 @@ }, "rbibutils": { "Package": "rbibutils", - "Version": "2.2.15", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1610,7 +1486,6 @@ }, "readxl": { "Package": "readxl", - "Version": "1.4.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1625,7 +1500,6 @@ }, "relimp": { "Package": "relimp", - "Version": "1.0-5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1637,14 +1511,12 @@ }, "rematch": { "Package": "rematch", - "Version": "2.0.0", "Source": "Repository", "Repository": "RSPM", "Hash": "cbff1b666c6fa6d21202f07e2318d4f1" }, "rematch2": { "Package": "rematch2", - "Version": "2.1.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1654,7 +1526,6 @@ }, "renv": { "Package": "renv", - "Version": "1.0.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1664,7 +1535,6 @@ }, "rgl": { "Package": "rgl", - "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1686,7 +1556,6 @@ }, "rlang": { "Package": "rlang", - "Version": "1.1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1697,7 +1566,6 @@ }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.25", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1721,7 +1589,6 @@ }, "rootSolve": { "Package": "rootSolve", - "Version": "1.8.2.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1734,7 +1601,6 @@ }, "rprojroot": { "Package": "rprojroot", - "Version": "2.0.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1744,7 +1610,6 @@ }, "rstpm2": { "Package": "rstpm2", - "Version": "1.6.2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1768,14 +1633,12 @@ }, "rstudioapi": { "Package": "rstudioapi", - "Version": "0.15.0", "Source": "Repository", "Repository": "RSPM", "Hash": "5564500e25cffad9e22244ced1379887" }, "sass": { "Package": "sass", - "Version": "0.4.7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1789,7 +1652,6 @@ }, "scales": { "Package": "scales", - "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1807,7 +1669,6 @@ }, "shiny": { "Package": "shiny", - "Version": "1.7.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1841,7 +1702,6 @@ }, "shinyWidgets": { "Package": "shinyWidgets", - "Version": "0.8.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1859,7 +1719,6 @@ }, "shinyjs": { "Package": "shinyjs", - "Version": "2.1.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1872,7 +1731,6 @@ }, "sourcetools": { "Package": "sourcetools", - "Version": "0.1.7-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1882,7 +1740,6 @@ }, "statmod": { "Package": "statmod", - "Version": "1.5.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1894,7 +1751,6 @@ }, "stringi": { "Package": "stringi", - "Version": "1.7.12", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1907,7 +1763,6 @@ }, "stringr": { "Package": "stringr", - "Version": "1.5.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1924,7 +1779,6 @@ }, "survival": { "Package": "survival", - "Version": "3.5-7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1940,14 +1794,12 @@ }, "sys": { "Package": "sys", - "Version": "3.4.2", "Source": "Repository", "Repository": "CRAN", "Hash": "3a1be13d68d47a8cd0bfd74739ca1555" }, "testthat": { "Package": "testthat", - "Version": "3.2.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1977,7 +1829,6 @@ }, "tibble": { "Package": "tibble", - "Version": "3.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1996,7 +1847,6 @@ }, "tidyr": { "Package": "tidyr", - "Version": "1.3.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2019,7 +1869,6 @@ }, "tidyselect": { "Package": "tidyselect", - "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2035,7 +1884,6 @@ }, "tinytex": { "Package": "tinytex", - "Version": "0.47", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2045,7 +1893,6 @@ }, "tolerance": { "Package": "tolerance", - "Version": "2.0.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2058,7 +1905,6 @@ }, "triangle": { "Package": "triangle", - "Version": "1.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2071,7 +1917,6 @@ }, "truncnorm": { "Package": "truncnorm", - "Version": "1.0-9", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2081,7 +1926,6 @@ }, "utf8": { "Package": "utf8", - "Version": "1.2.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2091,7 +1935,6 @@ }, "vcd": { "Package": "vcd", - "Version": "1.4-11", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2108,7 +1951,6 @@ }, "vcdExtra": { "Package": "vcdExtra", - "Version": "0.8-5", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2133,7 +1975,6 @@ }, "vctrs": { "Package": "vctrs", - "Version": "0.6.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2147,7 +1988,6 @@ }, "viridisLite": { "Package": "viridisLite", - "Version": "0.4.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2157,7 +1997,6 @@ }, "waldo": { "Package": "waldo", - "Version": "0.5.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -2174,7 +2013,6 @@ }, "withr": { "Package": "withr", - "Version": "2.5.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2187,7 +2025,6 @@ }, "xfun": { "Package": "xfun", - "Version": "0.40", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2198,7 +2035,6 @@ }, "xml2": { "Package": "xml2", - "Version": "1.3.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2209,7 +2045,6 @@ }, "xtable": { "Package": "xtable", - "Version": "1.8-4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2221,14 +2056,12 @@ }, "yaml": { "Package": "yaml", - "Version": "2.3.7", "Source": "Repository", "Repository": "CRAN", "Hash": "0d0056cc5383fbc240ccd0cb584bf436" }, "zoo": { "Package": "zoo", - "Version": "1.8-12", "Source": "Repository", "Repository": "CRAN", "Requirements": [ diff --git a/renv/.DS_Store b/renv/.DS_Store new file mode 100644 index 0000000..54e75b9 Binary files /dev/null and b/renv/.DS_Store differ diff --git a/renv/activate.R b/renv/activate.R index cb5401f..39cf39f 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -6,7 +6,9 @@ local({ attr(version, "sha") <- NULL # the project directory - project <- getwd() + project <- Sys.getenv("RENV_PROJECT") + if (!nzchar(project)) + project <- getwd() # use start-up diagnostics if enabled diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") @@ -31,8 +33,16 @@ local({ if (!is.null(override)) return(override) + # if we're being run in a context where R_LIBS is already set, + # don't load -- presumably we're being run as a sub-process and + # the parent process has already set up library paths for us + rcmd <- Sys.getenv("R_CMD", unset = NA) + rlibs <- Sys.getenv("R_LIBS", unset = NA) + if (!is.na(rlibs) && !is.na(rcmd)) + return(FALSE) + # next, check environment variables - # TODO: prefer using the configuration one in the future + # prefer using the configuration one in the future envvars <- c( "RENV_CONFIG_AUTOLOADER_ENABLED", "RENV_AUTOLOADER_ENABLED", @@ -50,9 +60,22 @@ local({ }) - if (!enabled) + # bail if we're not enabled + if (!enabled) { + + # if we're not enabled, we might still need to manually load + # the user profile here + profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile") + if (file.exists(profile)) { + cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE") + if (tolower(cfg) %in% c("true", "t", "1")) + sys.source(profile, envir = globalenv()) + } + return(FALSE) + } + # avoid recursion if (identical(getOption("renv.autoloader.running"), TRUE)) { warning("ignoring recursive attempt to run renv autoloader") @@ -75,6 +98,66 @@ local({ unloadNamespace("renv") # load bootstrap tools + ansify <- function(text) { + if (renv_ansify_enabled()) + renv_ansify_enhanced(text) + else + renv_ansify_default(text) + } + + renv_ansify_enabled <- function() { + + override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA) + if (!is.na(override)) + return(as.logical(override)) + + pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA) + if (identical(pane, "build")) + return(FALSE) + + testthat <- Sys.getenv("TESTTHAT", unset = "false") + if (tolower(testthat) %in% "true") + return(FALSE) + + iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false") + if (tolower(iderun) %in% "false") + return(FALSE) + + TRUE + + } + + renv_ansify_default <- function(text) { + text + } + + renv_ansify_enhanced <- function(text) { + + # R help links + pattern <- "`\\?(renv::(?:[^`])+)`" + replacement <- "`\033]8;;x-r-help:\\1\a?\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # runnable code + pattern <- "`(renv::(?:[^`])+)`" + replacement <- "`\033]8;;x-r-run:\\1\a\\1\033]8;;\a`" + text <- gsub(pattern, replacement, text, perl = TRUE) + + # return ansified text + text + + } + + renv_ansify_init <- function() { + + envir <- renv_envir_self() + if (renv_ansify_enabled()) + assign("ansify", renv_ansify_enhanced, envir = envir) + else + assign("ansify", renv_ansify_default, envir = envir) + + } + `%||%` <- function(x, y) { if (is.null(x)) y else x } @@ -108,8 +191,22 @@ local({ } - startswith <- function(string, prefix) { - substring(string, 1, nchar(prefix)) == prefix + heredoc <- function(text, leave = 0) { + + # remove leading, trailing whitespace + trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text) + + # split into lines + lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]] + + # compute common indent + indent <- regexpr("[^[:space:]]", lines) + common <- min(setdiff(indent, -1L)) - leave + text <- paste(substring(lines, common), collapse = "\n") + + # substitute in ANSI links for executable renv code + ansify(text) + } bootstrap <- function(version, library) { @@ -267,8 +364,11 @@ local({ quiet = TRUE ) - if ("headers" %in% names(formals(utils::download.file))) - args$headers <- renv_bootstrap_download_custom_headers(url) + if ("headers" %in% names(formals(utils::download.file))) { + headers <- renv_bootstrap_download_custom_headers(url) + if (length(headers) && is.character(headers)) + args$headers <- headers + } do.call(utils::download.file, args) @@ -347,10 +447,21 @@ local({ for (type in types) { for (repos in renv_bootstrap_repos()) { + # build arguments for utils::available.packages() call + args <- list(type = type, repos = repos) + + # add custom headers if available -- note that + # utils::available.packages() will pass this to download.file() + if ("headers" %in% names(formals(utils::download.file))) { + headers <- renv_bootstrap_download_custom_headers(repos) + if (length(headers) && is.character(headers)) + args$headers <- headers + } + # retrieve package database db <- tryCatch( as.data.frame( - utils::available.packages(type = type, repos = repos), + do.call(utils::available.packages, args), stringsAsFactors = FALSE ), error = identity @@ -432,6 +543,14 @@ local({ } + renv_bootstrap_github_token <- function() { + for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) { + envval <- Sys.getenv(envvar, unset = NA) + if (!is.na(envval)) + return(envval) + } + } + renv_bootstrap_download_github <- function(version) { enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE") @@ -439,16 +558,19 @@ local({ return(FALSE) # prepare download options - pat <- Sys.getenv("GITHUB_PAT") - if (nzchar(Sys.which("curl")) && nzchar(pat)) { + token <- renv_bootstrap_github_token() + if (is.null(token)) + token <- "" + + if (nzchar(Sys.which("curl")) && nzchar(token)) { fmt <- "--location --fail --header \"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "curl", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) - } else if (nzchar(Sys.which("wget")) && nzchar(pat)) { + } else if (nzchar(Sys.which("wget")) && nzchar(token)) { fmt <- "--header=\"Authorization: token %s\"" - extra <- sprintf(fmt, pat) + extra <- sprintf(fmt, token) saved <- options("download.file.method", "download.file.extra") options(download.file.method = "wget", download.file.extra = extra) on.exit(do.call(base::options, saved), add = TRUE) @@ -610,6 +732,9 @@ local({ # if the user has requested an automatic prefix, generate it auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA) + if (is.na(auto) && getRversion() >= "4.4.0") + auto <- "TRUE" + if (auto %in% c("TRUE", "True", "true", "1")) return(renv_bootstrap_platform_prefix_auto()) @@ -801,24 +926,23 @@ local({ # the loaded version of renv doesn't match the requested version; # give the user instructions on how to proceed - remote <- if (!is.null(description[["RemoteSha"]])) { + dev <- identical(description[["RemoteType"]], "github") + remote <- if (dev) paste("rstudio/renv", description[["RemoteSha"]], sep = "@") - } else { + else paste("renv", description[["Version"]], sep = "@") - } # display both loaded version + sha if available friendly <- renv_bootstrap_version_friendly( version = description[["Version"]], - sha = description[["RemoteSha"]] + sha = if (dev) description[["RemoteSha"]] ) - fmt <- paste( - "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", - sep = "\n" - ) + fmt <- heredoc(" + renv %1$s was loaded from project library, but this project is configured to use renv %2$s. + - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile. + - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library. + ") catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) FALSE @@ -826,8 +950,14 @@ local({ } renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] - is.character(expected) && startswith(expected, version) + if (!is.character(expected)) + return(FALSE) + + pattern <- sprintf("^\\Q%s\\E", version) + grepl(pattern, expected, perl = TRUE) + } renv_bootstrap_validate_version_release <- function(version, description) { @@ -1007,10 +1137,10 @@ local({ renv_bootstrap_exec <- function(project, libpath, version) { if (!renv_bootstrap_load(project, libpath, version)) - renv_bootstrap_run(version, libpath) + renv_bootstrap_run(project, libpath, version) } - renv_bootstrap_run <- function(version, libpath) { + renv_bootstrap_run <- function(project, libpath, version) { # perform bootstrap bootstrap(version, libpath) @@ -1021,7 +1151,7 @@ local({ # try again to load if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { - return(renv::load(project = getwd())) + return(renv::load(project = project)) } # failed to download or load renv; warn the user @@ -1041,7 +1171,7 @@ local({ # if jsonlite is loaded, use that instead if ("jsonlite" %in% loadedNamespaces()) { - json <- catch(renv_json_read_jsonlite(file, text)) + json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity) if (!inherits(json, "error")) return(json) @@ -1050,7 +1180,7 @@ local({ } # otherwise, fall back to the default JSON reader - json <- catch(renv_json_read_default(file, text)) + json <- tryCatch(renv_json_read_default(file, text), error = identity) if (!inherits(json, "error")) return(json) @@ -1063,102 +1193,105 @@ local({ } renv_json_read_jsonlite <- function(file = NULL, text = NULL) { - text <- paste(text %||% read(file), collapse = "\n") + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") jsonlite::fromJSON(txt = text, simplifyVector = FALSE) } - renv_json_read_default <- function(file = NULL, text = NULL) { - - # find strings in the JSON - text <- paste(text %||% read(file), collapse = "\n") - pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - locs <- gregexpr(pattern, text, perl = TRUE)[[1]] - - # if any are found, replace them with placeholders - replaced <- text - strings <- character() - replacements <- character() - - if (!identical(c(locs), -1L)) { - - # get the string values - starts <- locs - ends <- locs + attr(locs, "match.length") - 1L - strings <- substring(text, starts, ends) - - # only keep those requiring escaping - strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE) - - # compute replacements - replacements <- sprintf('"\032%i\032"', seq_along(strings)) - - # replace the strings - mapply(function(string, replacement) { - replaced <<- sub(string, replacement, replaced, fixed = TRUE) - }, strings, replacements) + renv_json_read_patterns <- function() { + + list( + + # objects + list("{", "\t\n\tobject(\t\n\t"), + list("}", "\t\n\t)\t\n\t"), + + # arrays + list("[", "\t\n\tarray(\t\n\t"), + list("]", "\n\t\n)\n\t\n"), + + # maps + list(":", "\t\n\t=\t\n\t") + + ) + + } + renv_json_read_envir <- function() { + + envir <- new.env(parent = emptyenv()) + + envir[["+"]] <- `+` + envir[["-"]] <- `-` + + envir[["object"]] <- function(...) { + result <- list(...) + names(result) <- as.character(names(result)) + result } - - # transform the JSON into something the R parser understands - transformed <- replaced - transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE) - transformed <- gsub("[[{]", "list(", transformed, perl = TRUE) - transformed <- gsub("[]}]", ")", transformed, perl = TRUE) - transformed <- gsub(":", "=", transformed, fixed = TRUE) - text <- paste(transformed, collapse = "\n") - - # parse it - json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]] - - # construct map between source strings, replaced strings - map <- as.character(parse(text = strings)) - names(map) <- as.character(parse(text = replacements)) - - # convert to list - map <- as.list(map) - - # remap strings in object - remapped <- renv_json_remap(json, map) - - # evaluate - eval(remapped, envir = baseenv()) - + + envir[["array"]] <- list + + envir[["true"]] <- TRUE + envir[["false"]] <- FALSE + envir[["null"]] <- NULL + + envir + } - renv_json_remap <- function(json, map) { - - # fix names - if (!is.null(names(json))) { - lhs <- match(names(json), names(map), nomatch = 0L) - rhs <- match(names(map), names(json), nomatch = 0L) - names(json)[rhs] <- map[lhs] + renv_json_read_remap <- function(object, patterns) { + + # repair names if necessary + if (!is.null(names(object))) { + + nms <- names(object) + for (pattern in patterns) + nms <- gsub(pattern[[2L]], pattern[[1L]], nms, fixed = TRUE) + names(object) <- nms + } - - # fix values - if (is.character(json)) - return(map[[json]] %||% json) - - # handle true, false, null - if (is.name(json)) { - text <- as.character(json) - if (text == "true") - return(TRUE) - else if (text == "false") - return(FALSE) - else if (text == "null") - return(NULL) + + # repair strings if necessary + if (is.character(object)) { + for (pattern in patterns) + object <- gsub(pattern[[2L]], pattern[[1L]], object, fixed = TRUE) } + + # recurse for other objects + if (is.recursive(object)) + for (i in seq_along(object)) + object[i] <- list(renv_json_read_remap(object[[i]], patterns)) + + # return remapped object + object + + } - # recurse - if (is.recursive(json)) { - for (i in seq_along(json)) { - json[i] <- list(renv_json_remap(json[[i]], map)) - } - } + renv_json_read_default <- function(file = NULL, text = NULL) { - json + # read json text + text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") + + # convert into something the R parser will understand + patterns <- renv_json_read_patterns() + transformed <- text + for (pattern in patterns) + transformed <- gsub(pattern[[1L]], pattern[[2L]], transformed, fixed = TRUE) + + # parse it + rfile <- tempfile("renv-json-", fileext = ".R") + on.exit(unlink(rfile), add = TRUE) + writeLines(transformed, con = rfile) + json <- parse(rfile, keep.source = FALSE, srcfile = NULL)[[1L]] + # evaluate in safe environment + result <- eval(json, envir = renv_json_read_envir()) + + # fix up strings if necessary + renv_json_read_remap(result, patterns) + } + # load the renv profile, if any renv_bootstrap_profile_load(project) diff --git a/server.R b/server.R index bd70f09..f469497 100644 --- a/server.R +++ b/server.R @@ -1,267 +1,283 @@ -# SOCR Probability Distribution Calculator -# Version 0.9 -# Updated December 8th by Bole Li and Joonseop Kim at the University of Michigan -SOCR -# Orginally created by Jared(Tianyi) Chai - -# This is a SOCR Interactive Graphical Probability Distribution Calculator -# You can run the application by clicking -# the 'Run App' button above. - -# ----------------------- Server.R ----------------------- # -# For backend calculations -library(xml2) -library(shinyjs) -library(flexsurv) -library(vcdExtra) -library(evd) -library(DescTools) -library(shiny) -library(triangle) -library(plotly) -library(stringr) -library(VGAM) -library(BayesTools) -library(extraDistr) -library(statmod) -library(truncnorm) -library(tolerance) -library(chi) -library(Rlab) -library(shinyWidgets) -library(circular) -library(mnormt) -library(ExtDist) -library(VaRES) -library(shinyjs) -shinyjs::useShinyjs() -source("renderMainPlot.R") -source("renderProbability.R") - -shinyServer( - function(input, output, session) { - datasetShown <- reactiveVal(iris) - # ----------------------- Update Distribution Type and Function Type according to URL handle ----------------------- # - observe({ - query <- parseQueryString(session$clientData$url_search) - if (!is.null(query[["d"]])) { - updateSelectInput(session, "Distribution", selected = distributions[as.numeric(query[["d"]])]) - updateSelectInput(session, "FunctionType", selected = "PDF/PMF") - if (!is.null(query[["t"]])) { - updateSelectInput(session, "FunctionType", selected = query[["t"]]) - } - } - # ----------------------- Update Range of Probability Calculation according to Range of X ----------------------- # - updateSliderInput(session, - "probrange", - value = 0, - min = input$plotrange[1], - max = input$plotrange[2], - step = 0.01 - ) - updateNumericInput(session, - "probrangeNumMin", - value = 0, - min = input$plotrangeNumMin, - max = input$plotrangeNumMax - ) - updateNumericInput(session, - "probrangeNumMax", - value = 0, - min = input$plotrangeNumMin, - max = input$plotrangeNumMax - ) - }) - - observeEvent(input$fitParams, { - updateTextInput(session, "FunctionType", value = "PDF/PMF") - distributionInfo <- distributionInfoList[[input$Distribution]] - if (is.null(dataset)) { - showNotification("Dataset is not specified.", type = "error", duration = 2) - } else if (is.null((distributionInfo$fitFunc))) { - showNotification("Fitting this distribution is not supported yet.", type = "error", duration = 2) - } else { - fit_result <- distributionInfo$fitFunc(dataset[, input$outcome]) - for (i in 1:length(fit_result$estimate)) { - inputName <- distributionInfo$inputNames[[i]] - fitted_parameter <- round(fit_result$estimate[[i]], digits = 4) - updateTextInput(session, inputName, value = fitted_parameter) - session$sendCustomMessage("highlightTextInput", inputName) - } - if (distributionInfo$isWithSD) { - # update the plot range, make it centered at the mean - oldPlotRange <- input$plotrange - halfLength <- (oldPlotRange[2] - oldPlotRange[1]) / 2 - updateSliderInput(session, - "plotrange", - label = NULL, - value = c(fit_result$estimate[[1]] - halfLength, fit_result$estimate[[1]] + halfLength), - min = -1000, - max = 1000, - step = NULL, - timeFormat = NULL, - timezone = NULL - ) - } - } - }) - - observe({ - if (input$numericalValues == 0 && input$Distribution %in% distWithSD) { - shinyjs::enable("SDNum") - # FIXME: This is not working - # shinyjs::toggle("SDNumColumn", condition = TRUE) - } else { - shinyjs::disable("SDNum") - # FIXME: This is not working - # shinyjs::toggle("SDNumColumn", condition = FALSE) - } - }) - - # Generate text to display current parameters and their values - output$currentParameters <- renderUI( - HTML({ - distributionInfo <- distributionInfoList[[input$Distribution]] - paramValues <- lapply(seq_along(distributionInfo$labels), function(i) { - label <- distributionInfo$labels[[i]] - inputName <- distributionInfo$inputNames[[i]] - paste("", label, ": ", input[[inputName]], "") - }) - # Combine the distribution name and parameter values into a single string - paste("Current Parameters:
", paste(paramValues, collapse = "
")) - }) - ) - - observeEvent(input$CalcModelerTabsetPanel, { - if (input$CalcModelerTabsetPanel == "Modeler") { - updateTextInput(session, "FunctionType", value = "") - } - }) - - # Reactive function to read uploaded file and update dataset - observeEvent(input$file, { - req(input$file) - dataset <<- read.csv(input$file$datapath) - datasetShown(dataset) - # Update choices for selectInput widgets - updateSelectInput(session, "outcome", choices = namedListOfFeatures(), selected = NULL) - updateSelectInput(session, "indepvar", choices = namedListOfFeatures(), selected = NULL) - }) - - # ----------------------- HelpMe ----------------------- # - observeEvent(input$vh.readme, { - showModal(modalDialog( - title = "Help / ReadMe", - HTML("
- SOCR Interactive Probability Distribution Calculator [Version: V.0.9] - The SOCR RShiny probability distribution calculators provide interactive vizualizations of probability densities, - mass functions, and cumulative distributions, e.g., bivariate normal distribution. -

- Acknowledgments -

- This work is supported in part by NIH grants P20 NR015331, UL1TR002240, P30 DK089503, UL1TR002240, - and NSF grants 1916425, 1734853, 1636840, 1416953, 0716055 and 1023115. Students, trainees, scholars, - and researchers from SOCR, BDDS, MIDAS, MICHR, and the broad R-statistical computing community have contributed ideas, - code, and support. -
- Developers
- Jared (Tianyi) Chai (chtianyi@umich.edu)
- Shihang Li (shihangl@umich.edu)
- Yongxiang Zhao (zyxleo@umich.edu)
- Bole Li (boleli@umich.edu)
- Joonseop Kim (joonkim@umich.edu)
- Ivo Dinov (dinov@med.umich.edu).

-
- "), - easyClose = TRUE - )) - }) - # ----------------------- Render Metadata Information from xml Database ----------------------- # - output$MetaData <- renderPrint({ - distType <- input$Distribution - distType <- tolower(str_replace_all(distType, "[^[:alnum:]]", "")) - counter <- 0 - for (i in 1:xml_len) { - j <- 1 - while (distributions_meta[[j, i * 2 - 1]] == "name") { - if (tolower(str_replace_all(distributions_meta[[1, i * 2]], "[^[:alnum:]]", "")) == distType) { - counter <- i - break - } else { - j <- j + 1 - } - } - } - outputstring <- "" - if (counter != 0) { - row <- 1 - while (distributions_meta[[row, counter * 2 - 1]] != "" && row < xml_wid) { - outputstring <- paste(outputstring, "", distributions_meta[[row, counter * 2 - 1]], ": ", distributions_meta[[row, counter * 2]], "\n", sep = "") - row <- row + 1 - } - } - withMathJax(helpText(HTML(outputstring))) - }) - # ----------------------- Render Main Plot ----------------------- # - renderMainPlot(input, output, session, dataset) - # ----------------------- Render Implementing Message ----------------------- # - output$Implementing <- renderText({ - if (input$Distribution %in% distToImpl) { - paste("The ", input$Distribution, " is still being implemented.", sep = "") - } - }) - # ----------------------- Calculate and Render Probability ----------------------- # - renderProbability(input, output, session) - - - # Imputation of categorical variables using Mode - getmode <- function(v) { - v <- v[nchar(as.character(v)) > 0] - uniqv <- unique(v) - uniqv[which.max(tabulate(match(v, uniqv)))] - } - - # Render the DataTable dynamically based on the reactive dataset - output$tbl <- DT::renderDataTable({ - # Use isolate to prevent invalidation of the reactive expression on initial render - DT::datatable(datasetShown(), options = list(lengthChange = FALSE)) - }) - - # Regression output - output$summary <- renderPrint({ - fit <- lm(unlist(dataset[, input$outcome]) ~ unlist(dataset[, input$indepvar])) - names(fit$coefficients) <- c("Intercept", input$var2) - fitCurrent <- fit - summary(fit) - }) - - # Scatterplot output - output$scatterplot <- renderPlotly({ - plot_ly( - x = ~ unlist(dataset[, input$indepvar]), y = ~ unlist(dataset[, input$outcome]), - type = "scatter", mode = "markers", name = "Data" - ) %>% - add_lines( - x = ~ unlist(dataset[, input$indepvar]), - y = ~ (lm(unlist(dataset[, input$outcome]) ~ unlist(dataset[, input$indepvar]))$fitted.values), - mode = "lines", name = "Linear Model" - ) %>% - add_lines( - x = ~ lowess(unlist(dataset[, input$indepvar]), unlist(dataset[, input$outcome]))$x, - y = ~ lowess(unlist(dataset[, input$indepvar]), unlist(dataset[, input$outcome]))$y, - mode = "lines", name = "LOESS" - ) %>% - add_markers( - x = mean(unlist(dataset[, input$indepvar])), y = mean(unlist(dataset[, input$outcome])), - name = "Center Point", marker = list(size = 20, color = "green", line = list(color = "yellow", width = 2)) - ) %>% - layout( - title = paste0( - "lm(", input$outcome, " ~ ", input$indepvar, - "), Cor(", input$indepvar, ",", input$outcome, ") = ", - round(cor(unlist(dataset[, input$indepvar]), unlist(dataset[, input$outcome])), 3) - ), - xaxis = list(title = input$indepvar), yaxis = list(title = input$outcome) - ) - }) - } -) +# SOCR Probability Distribution Calculator +# Version 0.9 +# Updated December 8th by Bole Li and Joonseop Kim at the University of Michigan -SOCR +# Orginally created by Jared(Tianyi) Chai + +# This is a SOCR Interactive Graphical Probability Distribution Calculator +# You can run the application by clicking +# the 'Run App' button above. + +# ----------------------- Server.R ----------------------- # +# For backend calculations +library(xml2) +library(shinyjs) +library(flexsurv) +library(vcdExtra) +library(evd) +library(DescTools) +library(shiny) +library(triangle) +library(plotly) +library(stringr) +library(VGAM) +library(BayesTools) +library(extraDistr) +library(statmod) +library(truncnorm) +library(tolerance) +library(chi) +library(Rlab) +library(shinyWidgets) +library(circular) +library(mnormt) +library(ExtDist) +library(VaRES) +library(shinyjs) +library(benford.analysis) +shinyjs::useShinyjs() +source("renderMainPlot.R") +source("renderProbability.R") + +shinyServer( + function(input, output, session) { + datasetShown <- reactiveVal(iris) + # ----------------------- Update Distribution Type and Function Type according to URL handle ----------------------- # + observe({ + query <- parseQueryString(session$clientData$url_search) + if (!is.null(query[["d"]])) { + updateSelectInput(session, "Distribution", selected = distributions[as.numeric(query[["d"]])]) + updateSelectInput(session, "FunctionType", selected = "PDF/PMF") + if (!is.null(query[["t"]])) { + updateSelectInput(session, "FunctionType", selected = query[["t"]]) + } + } + # ----------------------- Update Range of Probability Calculation according to Range of X ----------------------- # + updateSliderInput(session, + "probrange", + value = 0, + min = input$plotrange[1], + max = input$plotrange[2], + step = 0.01 + ) + updateNumericInput(session, + "probrangeNumMin", + value = 0, + min = input$plotrangeNumMin, + max = input$plotrangeNumMax + ) + updateNumericInput(session, + "probrangeNumMax", + value = 0, + min = input$plotrangeNumMin, + max = input$plotrangeNumMax + ) + }) + + observeEvent(input$fitParams, { + updateTextInput(session, "FunctionType", value = "PDF/PMF") + distributionInfo <- distributionInfoList[[input$Distribution]] + if (input$Distribution == "Bernoulli Distribution") { + if (is.null(dataset)) { + showNotification("Dataset is not specified.", type = "error", duration = 2) + } else if (!all(dataset[, input$outcome] %in% c(0, 1))) { + # Show a warning if the dataset is not binary + showNotification("Dataset must be binary for the Bernoulli distribution.", type = "error", duration = 4) + } + } + # Check if fitting is supported for other distributions + + + if (is.null(dataset)) { + showNotification("Dataset is not specified.", type = "error", duration = 2) + } else if (is.null((distributionInfo$fitFunc))) { + showNotification("Fitting this distribution is not supported yet.", type = "error", duration = 2) + } else { + fit_result <- distributionInfo$fitFunc(dataset[, input$outcome]) + #if (input$Distribution == "Circle Distribution") { + # selected_data <- dataset[, c(input$outcome, input$indepvar)] + # fit_result <- distributionInfo$fitFunc(selected_data) + #} + for (i in 1:length(fit_result$estimate)) { + inputName <- distributionInfo$inputNames[[i]] + fitted_parameter <- round(fit_result$estimate[[i]], digits = 4) + updateTextInput(session, inputName, value = fitted_parameter) + session$sendCustomMessage("highlightTextInput", inputName) + } + if (distributionInfo$isWithSD) { + # update the plot range, make it centered at the mean + oldPlotRange <- input$plotrange + halfLength <- (oldPlotRange[2] - oldPlotRange[1]) / 2 + updateSliderInput(session, + "plotrange", + label = NULL, + value = c(fit_result$estimate[[1]] - halfLength, fit_result$estimate[[1]] + halfLength), + min = -1000, + max = 1000, + step = NULL, + timeFormat = NULL, + timezone = NULL + ) + } + } + }) + + observe({ + if (input$numericalValues == 0 && input$Distribution %in% distWithSD) { + shinyjs::enable("SDNum") + # FIXME: This is not working + # shinyjs::toggle("SDNumColumn", condition = TRUE) + } else { + shinyjs::disable("SDNum") + # FIXME: This is not working + # shinyjs::toggle("SDNumColumn", condition = FALSE) + } + }) + + # Generate text to display current parameters and their values + output$currentParameters <- renderUI( + HTML({ + distributionInfo <- distributionInfoList[[input$Distribution]] + paramValues <- lapply(seq_along(distributionInfo$labels), function(i) { + label <- distributionInfo$labels[[i]] + inputName <- distributionInfo$inputNames[[i]] + paste("", label, ": ", input[[inputName]], "") + }) + # Combine the distribution name and parameter values into a single string + paste("Current Parameters:
", paste(paramValues, collapse = "
")) + }) + ) + + observeEvent(input$CalcModelerTabsetPanel, { + if (input$CalcModelerTabsetPanel == "Modeler") { + updateTextInput(session, "FunctionType", value = "") + } + }) + + # Reactive function to read uploaded file and update dataset + observeEvent(input$file, { + req(input$file) + dataset <<- read.csv(input$file$datapath) + datasetShown(dataset) + # Update choices for selectInput widgets + updateSelectInput(session, "outcome", choices = namedListOfFeatures(), selected = NULL) + updateSelectInput(session, "indepvar", choices = namedListOfFeatures(), selected = NULL) + }) + + # ----------------------- HelpMe ----------------------- # + observeEvent(input$vh.readme, { + showModal(modalDialog( + title = "Help / ReadMe", + HTML("
+ SOCR Interactive Probability Distribution Calculator [Version: V.0.9] + The SOCR RShiny probability distribution calculators provide interactive vizualizations of probability densities, + mass functions, and cumulative distributions, e.g., bivariate normal distribution. +

+ Acknowledgments +

+ This work is supported in part by NIH grants P20 NR015331, UL1TR002240, P30 DK089503, UL1TR002240, + and NSF grants 1916425, 1734853, 1636840, 1416953, 0716055 and 1023115. Students, trainees, scholars, + and researchers from SOCR, BDDS, MIDAS, MICHR, and the broad R-statistical computing community have contributed ideas, + code, and support. +
+ Developers
+ Jared (Tianyi) Chai (chtianyi@umich.edu)
+ Shihang Li (shihangl@umich.edu)
+ Yongxiang Zhao (zyxleo@umich.edu)
+ Bole Li (boleli@umich.edu)
+ Joonseop Kim (joonkim@umich.edu)
+ Ivo Dinov (dinov@med.umich.edu).

+
+ "), + easyClose = TRUE + )) + }) + # ----------------------- Render Metadata Information from xml Database ----------------------- # + output$MetaData <- renderPrint({ + distType <- input$Distribution + distType <- tolower(str_replace_all(distType, "[^[:alnum:]]", "")) + counter <- 0 + for (i in 1:xml_len) { + j <- 1 + while (distributions_meta[[j, i * 2 - 1]] == "name") { + if (tolower(str_replace_all(distributions_meta[[1, i * 2]], "[^[:alnum:]]", "")) == distType) { + counter <- i + break + } else { + j <- j + 1 + } + } + } + outputstring <- "" + if (counter != 0) { + row <- 1 + while (distributions_meta[[row, counter * 2 - 1]] != "" && row < xml_wid) { + outputstring <- paste(outputstring, "", distributions_meta[[row, counter * 2 - 1]], ": ", distributions_meta[[row, counter * 2]], "\n", sep = "") + row <- row + 1 + } + } + withMathJax(helpText(HTML(outputstring))) + }) + # ----------------------- Render Main Plot ----------------------- # + renderMainPlot(input, output, session, dataset) + # ----------------------- Render Implementing Message ----------------------- # + output$Implementing <- renderText({ + if (input$Distribution %in% distToImpl) { + paste("The ", input$Distribution, " is still being implemented.", sep = "") + } + }) + # ----------------------- Calculate and Render Probability ----------------------- # + renderProbability(input, output, session) + + + # Imputation of categorical variables using Mode + getmode <- function(v) { + v <- v[nchar(as.character(v)) > 0] + uniqv <- unique(v) + uniqv[which.max(tabulate(match(v, uniqv)))] + } + + # Render the DataTable dynamically based on the reactive dataset + output$tbl <- DT::renderDataTable({ + # Use isolate to prevent invalidation of the reactive expression on initial render + DT::datatable(datasetShown(), options = list(lengthChange = FALSE)) + }) + + # Regression output + output$summary <- renderPrint({ + fit <- lm(unlist(dataset[, input$outcome]) ~ unlist(dataset[, input$indepvar])) + names(fit$coefficients) <- c("Intercept", input$var2) + fitCurrent <- fit + summary(fit) + }) + + # Scatterplot output + output$scatterplot <- renderPlotly({ + plot_ly( + x = ~ unlist(dataset[, input$indepvar]), y = ~ unlist(dataset[, input$outcome]), + type = "scatter", mode = "markers", name = "Data" + ) %>% + add_lines( + x = ~ unlist(dataset[, input$indepvar]), + y = ~ (lm(unlist(dataset[, input$outcome]) ~ unlist(dataset[, input$indepvar]))$fitted.values), + mode = "lines", name = "Linear Model" + ) %>% + add_lines( + x = ~ lowess(unlist(dataset[, input$indepvar]), unlist(dataset[, input$outcome]))$x, + y = ~ lowess(unlist(dataset[, input$indepvar]), unlist(dataset[, input$outcome]))$y, + mode = "lines", name = "LOESS" + ) %>% + add_markers( + x = mean(unlist(dataset[, input$indepvar])), y = mean(unlist(dataset[, input$outcome])), + name = "Center Point", marker = list(size = 20, color = "green", line = list(color = "yellow", width = 2)) + ) %>% + layout( + title = paste0( + "lm(", input$outcome, " ~ ", input$indepvar, + "), Cor(", input$indepvar, ",", input$outcome, ") = ", + round(cor(unlist(dataset[, input$indepvar]), unlist(dataset[, input$outcome])), 3) + ), + xaxis = list(title = input$indepvar), yaxis = list(title = input$outcome) + ) + }) + } +)