Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion R/app_server.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
##########################################################
# RTutor.AI | A Shiny app for chatting with your data.
# Author: Xijin Ge | ge@orditus.com
# © 2024 Orditus LLC
# © 2025 Orditus LLC
# No warranty & not for commercial use without a license.
##########################################################

Expand Down
4 changes: 2 additions & 2 deletions R/app_ui.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
##########################################################
# RTutor.AI | A Shiny app for chatting with your data.
# Author: Xijin Ge | ge@orditus.com
# © 2024 Orditus LLC
# © 2025 Orditus LLC
# No warranty & not for commercial use without a license.
##########################################################

Expand All @@ -25,7 +25,7 @@ app_ui <- function(request) {
tags$footer(
style = "position: fixed;bottom: 0;width: 100%;background-color: #F6FFF5;
padding: 10px;text-align: center;z-index: 99;",
span("© 2024 Orditus LLC"),
span("© 2025 Orditus LLC"),
HTML("&nbsp;"), # Adds space
actionLink(inputId = "ppolicy", "Privacy Policy"),
HTML("&nbsp;"),
Expand Down
233 changes: 233 additions & 0 deletions R/mod_10_eda.R
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ mod_10_eda_ui <- function(id) {
),
uiOutput(ns("eda_report_ui"))
)
),
tabPanel(
title = "Neural Net Reports",
div(style = "margin-left: 20px;",
hr(class = "custom-hr-thick"),
h4(strong("Neural Net Analysis"),
style = "font-size: 24px;"
),
uiOutput(ns("nnet_report_ui"))
)
)
)
)
Expand Down Expand Up @@ -876,5 +886,228 @@ mod_10_eda_serv <- function(id, selected_dataset_name, use_python,
}
)


##### RTutor NNet Report #####
# UI for Neural Network Tab
output$nnet_report_ui <- renderUI({
req(selected_dataset_name() != no_data)
req(!use_python())
req(!is.null(current_data()))
df <- ggpairs_data()

# Calculate the number of levels for the selected target variable
# (required info for binary classification)
num_levels <- 0
target_levels <- character(0)
if (!is.null(input$nnet_target_variable) && input$nnet_target_variable %in% colnames(df)) {
selected_col <- df[[input$nnet_target_variable]]

if (is.factor(selected_col)) { # if target is a factor
num_levels <- length(levels(selected_col)) # number of levels
if (num_levels == 2) { # if target is a binary factor
target_levels <- levels(selected_col) # vector of target levels
}
}
}

tagList(
br(),
fluidRow(
column(
width = 3,
actionButton(
inputId = ns("render_nnet_report_rtutor"),
label = strong("Render Report"),
class = "custom-action-button"
)
)
),
br(),
fluidRow(
column(
width = 6,
selectInput(
inputId = ns("nnet_target_variable"),
label = "Select a target variable:",
choices = colnames(df),
selected = input$nnet_target_variable,
multiple = FALSE
)
),
if (num_levels == 2) { # if target variable is binary factor
column(
width = 6,
selectInput(
inputId = ns("nnet_positive_class"),
label = "Select the positive class:",
choices = target_levels,
selected = if (length(target_levels) > 0) target_levels[1] else NULL # Default to the first level, or handle empty list
)
)
}
),
br(),
checkboxGroupInput(
inputId = ns("nnet_variables"),
label = "Select up to 20 predictor variables:",
choices = colnames(df),
selected = colnames(df)
),
br(),
selectInput(
inputId = ns("nnet_size_value"),
label = "Select number of neurons:",
choices = c(2:30),
selected = 6,
multiple = FALSE
)
)
})

# when user uploads a file and has more than 20 columns, only the first 20 is selected by nnet_variables.
observeEvent(input$user_file, {
req(selected_dataset_name() != no_data)
req(input$select_data == uploaded_data)
req(!use_python())
req(!is.null(ggpairs_data()))
df <- ggpairs_data()
if(ncol(df) > max_eda_var) {
updateCheckboxGroupInput(
session = session,
inputId = ns("nnet_variables"),
label = "Deselect variables to ignore (optional):",
choices = colnames(df),
selected = colnames(df)[1:max_eda_var]
)
}
})

# if user selects more than 20 columns for the nnet_variables, only the first 20 is selected by nnet_variables. Show a warning.
observeEvent(c(input$nnet_variables, input$nnet_target_variable), {
req(!use_python())
req(!is.null(ggpairs_data()))

selected_var <- input$nnet_variables
update_selection <- FALSE
# if the selected target variable is not included in the nnet_variables, add it to the top of the list.
if (!(input$nnet_target_variable %in% selected_var)) {
selected_var <- c(input$nnet_target_variable, selected_var)
update_selection <- TRUE
}

if(length(selected_var) > max_eda_var) {
selected_var <- selected_var[1:max_eda_var]

showNotification(
ui = paste("Only the first 20 variables are selected for EDA.
Please deselect some variables to continue."),
id = "nnet_variables_warning",
duration = 5,
type = "error"
)
update_selection <- TRUE
}

# if target variable is selected, add to it; if too many, only keep the first 20
if(update_selection){
updateCheckboxGroupInput(
session = session,
inputId = ns("nnet_variables"),
label = "Deselect variables to ignore (optional):",
choices = colnames(ggpairs_data()),
selected = selected_var
)
}
})

nnet_file <- reactiveVal(NULL)

observeEvent(input$render_nnet_report_rtutor, {
req(selected_dataset_name() != no_data)
req(!use_python())
req(!is.null(current_data()))


withProgress(message = "Generating Report (5 minutes)", {
incProgress(0.2)
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
tempReport <- file.path(tempdir(), "RTutor_NNet.Rmd")
# tempReport
tempReport <- gsub("\\", "/", tempReport, fixed = TRUE)
output_file <- gsub("Rmd$", "html", tempReport)
# This should retrieve the project location on your device:
# "C:/Users/bdere/Documents/GitHub/idepGolem"
#wd <- getwd()

markdown_location <- app_sys("app/www/nnet.Rmd")
file.copy(from = markdown_location, to = tempReport, overwrite = TRUE)


# Extract negative class for binary classification
negative_class <- if (!is.null(input$nnet_positive_class)) {
setdiff(levels(ggpairs_data()[[input$nnet_target_variable]]), input$nnet_positive_class)
} else {
NULL
}

# Set up parameters to pass to Rmd document
params <- list(
df = ggpairs_data()[, input$nnet_variables],
target = input$nnet_target_variable,
predictors = input$nnet_variables,
size = input$nnet_size_value,
positive_class_variable = input$nnet_positive_class,
negative_class_variable = negative_class
)
req(params)
# Knit the document, passing in the `params` list, and eval it in a
# child of the global environment (this isolates the code in the document
# from the code in this app).
tryCatch({
rmarkdown::render(
input = tempReport, # markdown_location,
output_file = output_file,
params = params,
envir = new.env(parent = globalenv())
)
},
error = function(e) {
showNotification(
ui = paste("Error when generating the report. Please try again."),
id = "nnet_report_error",
duration = 5,
type = "error"
)
},
finally = {
nnet_file(output_file)
# show modal with download button
showModal(modalDialog(
title = "Successfully rendered the report!",
downloadButton(
outputId = ns("nnet_report_rtutor"),
label = "Download"
),
easyClose = TRUE
))
}
)
})
})

# Markdown report
output$nnet_report_rtutor <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "RTutor_NNet.html",
content = function(file) {
validate(
need(!is.null(nnet_file()), "File not found.")
)
file.copy(from = nnet_file(), to = file, overwrite = TRUE)
}
)

})
}
4 changes: 2 additions & 2 deletions R/mod_12_about.R
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ mod_12_about_ui <- function(id) {
),
p(
"Explore our other AI tools at ",
a("Chatlize.ai",
href = "https://chatlize.ai/",
a("Datably.ai",
href = "https://datably.ai/",
target = "_blank"
),
style = "font-size: 23px;padding-left: 20px;padding-right: 20px;"
Expand Down
6 changes: 3 additions & 3 deletions R/mod_14_first_time_user_ui.r
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ mod_14_first_time_user_ui <- function(id) {
),
h4("Also try ",
a(
"Chatlize.ai,",
href = "https://chatlize.ai",
"Datably.ai,",
href = "https://datably.ai",
target = "_blank"
),
" a more general platform for analyzing data through chats.
Expand Down Expand Up @@ -97,7 +97,7 @@ mod_14_first_time_user_ui <- function(id) {
tags$li(
"RTutor can only analyze traditional statistics data, where
rows are observations and columns are variables. For complex
data, try https://chatlize.ai."
data, try https://datably.ai."
),
tags$li(
"Once uploaded, your data is automatically loaded into R as a
Expand Down
Loading