I'm trying to get a function work within a shiny app, but it doesn't work as expected.
Outside of the app it works fine,
But within the app, it doesn't work:
Is it because the input$var isn't working as expected? (The checkbox also doesn't work and I'm still trying to figure that out.) My main question is about the function.
Code:
library(shiny)
if (interactive()) {
one <- function(.data, var, na = TRUE) {
if (na == FALSE)
return({
.data %>%
group_by({{var}}) %>%
drop_na() %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
if (na == TRUE)
return({
.data %>%
group_by({{var}}) %>%
# drop_na() %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
}
ui <- fluidPage(
selectInput("var", label = "Select Variable", choices = c(" ", names(mtcars))),
checkboxInput("check", "Display missing", FALSE),
tableOutput("value")
)
server <- function(input, output) {
output$value <- renderTable({
req(input$var)
if (input$check) ({
mtcars %>%
one(input$var, na = TRUE)
})
if(!input$check) ({
mtcars %>%
one(input$var, na = FALSE)
})
})
}
shinyApp(ui, server)
}
Dataset with missing values:
df <- data.frame(col1 = c(1:3, NA),
col2 = c("this", NA,"is", "text"),
col3 = c(TRUE, FALSE, TRUE, TRUE),
col4 = c(2.5, 4.2, 3.2, NA),
stringsAsFactors = FALSE)
input$var is a character value whereas one function is written for unquoted variables. You can change your function to work for character values.
Other changes that I did in the code are -
Replace na == FALSE and na == TRUE to !na and na respectively.
Since you want to keep the first value in selectInput as blank, used if(input$var != '') instead of req(input$var) because input$var would always have a value.
library(shiny)
library(dplyr)
if (interactive()) {
one <- function(.data, var, na = TRUE) {
if (!na)
return({
.data %>%
group_by(.data[[var]]) %>%
filter(!is.na(.data[[var]])) %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
if (na)
return({
.data %>%
group_by(.data[[var]]) %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
}
ui <- fluidPage(
selectInput("var", label = "Select Variable", choices = c("", names(df))),
checkboxInput("check", "Display missing", FALSE),
tableOutput("value")
)
server <- function(input, output) {
output$value <- renderTable({
if(input$var != '') {
data <- df %>% one(input$var, na = input$check)
return(data)
}
})
}
shinyApp(ui, server)
}
Use get() to accomplish your needs. Also, you can use .data[[!!input$var]] to get the appropriate name in the header of the displayed table.
one <- function(.data, var, na = TRUE) {
if (na == FALSE)
return({
.data %>%
group_by({{var}}) %>%
filter(!is.na({{var}})) %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
if (na == TRUE)
return({
.data %>%
group_by({{var}}) %>%
# drop_na() %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
}
ui <- fluidPage(
selectInput("var", label = "Select Variable", choices = c(" ",names(mtcars))),
checkboxInput("check", "Display missing", FALSE),
tableOutput("value")
)
server <- function(input, output) {
output$value <- renderTable({
if (!is.null(input$var)) {
if (input$var == " " | is.na(input$var)) {
df <- mtcars ## choose what you want to display when input$var is missing; NULL if you want to show nothing
}else {
df <- mtcars %>% one(.data[[!!input$var]], na = req(input$check))
}
}else df <- NULL
df
})
}
shinyApp(ui, server)
Related
I created a dynamic form using {gt} and {purrr} combined with a function that extracts the HTML of shiny::selectizeInput.
I need to ensure that inputs created dynamically with {purrr} are available for others operations.
How can I use shiny::req() for all inputs created dynamically?
# libraries
library(shiny)
library(magrittr)
# functions
selectizeInput_gt <- function(value, inputid, ...) {
as.character(shiny::selectizeInput(paste0(value, inputid),
...)) %>%
gt::html()
}
# datasets
number_tests <- 5
df <- data.frame("test_number" = 1:number_tests)
# UI
ui <- fluidPage(gt::gt_output(outputId = "table"))
# server
server <- function(input, output, session) {
output$table <- gt::render_gt({
req(df)
df %>%
tibble::rownames_to_column() %>%
dplyr::rowwise() %>%
dplyr::mutate(
rowname = as.numeric(rowname),
selectinput_column = purrr::map(
rowname,
.f = ~ selectizeInput_gt(
.x,
"_selectinput",
label = "",
choices = c("A", "B", "C")
)
)
) %>%
gt::gt()
})
}
# runApp
shinyApp(ui, server)
After a lot of fiddling, I figured out a way to use purrr::walk to pass the inputs to req(). To generate the inputs, I use purrr::map.
As a small example, I use the req() to prevent an error in a simple output that uses the values of the inputs.
# libraries
library(shiny)
library(magrittr)
# functions
selectizeInput_gt <- function(value, inputid, ...) {
as.character(shiny::selectizeInput(paste0(value, inputid),
...)) %>%
gt::html()
}
# datasets
number_tests <- 5
df <- data.frame("test_number" = 1:number_tests)
# UI
ui <- fluidPage(gt::gt_output(outputId = "table"),
textOutput("selections"))
# server
server <- function(input, output, session) {
output$table <- gt::render_gt({
req(df)
df %>%
tibble::rownames_to_column() %>%
dplyr::rowwise() %>%
dplyr::mutate(
rowname = as.numeric(rowname),
selectinput_column = purrr::map(
rowname,
.f = ~ selectizeInput_gt(
.x,
"_selectinput",
label = "",
choices = c("A", "B", "C")
)
)
) %>%
gt::gt()
})
output$selections <- renderText({
purrr::walk(purrr::map(paste0(df$test_number, "_selectinput"), ~input[[.]]), req)
paste(purrr::map_chr(paste0(df$test_number, "_selectinput"), ~input[[.]]))
})
}
# runApp
shinyApp(ui, server)
I am trying to create two corresponding selectInput lists. To do so I made two uiOutput in ui attached to renderUI in server. The renderUIs are linked to reactiveValues which should change according to input$* values.
And it does work until one point. The selection list is shrinking and can't go back to default (while in my opinion it should, based on second line of observeEvent).
I have a feeling that no matter what the input$* values are never null so the is.null() won't work.
I will apprecieate any help in this topic.
if (interactive()) {
library(dplyr)
library(shiny)
library(shinydashboard)
library(plotly)
library(DT)
library(tidyr)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
uiOutput('hair_filter'),
uiOutput('species_filter')
),
mainPanel( tableOutput('hairs'),
tableOutput('species'),
textOutput('text'),
textOutput('text2'),
tableOutput('hairfiltertable'),
tableOutput('speciesfiltertable')
)
))
server <- function(input, output, session){
starwars_full <- starwars %>%
as.data.frame() %>%
tibble::rownames_to_column(var = 'ID') %>%
transform(ID=as.numeric(ID), height=as.numeric(height), mass=as.numeric(mass), birth_year=as.numeric(birth_year)) %>%
group_by(ID, name, height,mass,hair_color, skin_color, eye_color, birth_year,sex,homeworld,species, films, vehicles, starships) %>%
summarise('cnt_films'=lengths(films),'cnt_vehicles'=lengths(vehicles),'cnt_ships'=lengths(starships))
#creating list of hair colors based on selected species
rv3 <- reactiveValues(hair_list = starwars_full %>%
separate_rows(hair_color,sep=", ") %>%
arrange(hair_color) %>%
as.data.frame() %>%
select(hair_color,species, name) %>%
distinct()
)
observeEvent(input$selected_from_dropdown_species,{
if(isTruthy(input$selected_from_dropdown_species))
{
rv3$hair_list <- starwars_full %>%
separate_rows(hair_color,sep=", ") %>%
arrange(hair_color) %>%
as.data.frame() %>%
select(hair_color,species, name) %>%
distinct() %>%
filter(species %in% input$selected_from_dropdown_species)
rv6$selected_species <- input$selected_from_dropdown_species
}
else
{
rv3$hair_list <- starwars_full %>%
separate_rows(hair_color,sep=", ") %>%
arrange(hair_color) %>%
as.data.frame() %>%
select(hair_color,species, name) %>%
distinct()
rv6$selected_species <- NULL
}
})
#creating species list, based on selected hair colors
rv4 <- reactiveValues(specie_list = starwars_full %>%
separate_rows(species,sep=", ") %>%
arrange(species) %>% as.data.frame() %>%
select(hair_color,species, name) %>%
distinct()
)
observeEvent(input$selected_from_dropdown_color,{
if(isTruthy(input$selected_from_dropdown_color))
{
rv4$specie_list <- starwars_full %>%
separate_rows(species,sep=", ") %>%
arrange(species) %>% as.data.frame() %>%
select(hair_color,species, name) %>%
distinct() %>%
filter(hair_color %in% input$selected_from_dropdown_color)
rv5$selected_colors <- input$selected_from_dropdown_color
}
else
{
rv4$specie_list <- starwars_full %>%
separate_rows(species,sep=", ") %>%
arrange(species) %>% as.data.frame() %>%
select(hair_color,species, name) %>%
distinct()
rv5$selected_colors <- NULL
}
})
rv5 <- reactiveValues(selected_colors = NULL)
rv6 <- reactiveValues(selected_species = NULL)
#selecinput of hair color
output$hair_filter = renderUI({
selectInput("selected_from_dropdown_color",
label ="Hair colors:",
choices=rv3$hair_list$hair_color,
multiple=TRUE,
selected=isolate(rv5$selected_colors))
})
#selectinput for species
output$species_filter = renderUI({
selectInput("selected_from_dropdown_species",
label ="Species",
choices=rv4$specie_list$species,
multiple=TRUE,
selected=isolate(rv6$selected_species))
})
output$hairs = renderTable({input$selected_from_dropdown_color})
output$species = renderTable({input$selected_from_dropdown_species})
output$text = renderPrint({print(input$selected_from_dropdown_color)})
output$text2 = renderPrint({print(input$selected_from_dropdown_species)})
output$hairfiltertable = renderTable({rv3$hair_list})
output$speciesfiltertable = renderTable({rv4$specie_list})
}
shinyApp(ui,server)
}
Edit:
We can use selectizeGroup from shinyWidgets to achieve the desired behaviour.
library(tidyverse)
library(shiny)
library(shinydashboard)
library(plotly)
library(DT)
library(tidyr)
library(shinyWidgets)
starwars_full <- starwars %>%
as.data.frame() %>%
rownames_to_column(var = "ID") %>%
transform(ID = as.numeric(ID), height = as.numeric(height), mass = as.numeric(mass), birth_year = as.numeric(birth_year)) %>%
group_by(ID, name, height, mass, hair_color, skin_color, eye_color, birth_year, sex, homeworld, species, films, vehicles, starships) %>%
summarise("cnt_films" = lengths(films), "cnt_vehicles" = lengths(vehicles), "cnt_ships" = lengths(starships))
starwars_species_hair <- starwars_full %>%
separate_rows(hair_color, sep = ", ") %>%
separate_rows(species, sep = ", ") %>%
select(hair_color, species, name)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectizeGroupUI(
id = "my-filters",
params = list(
hair_color = list(inputId = "hair_color", title = "Hair color:"),
species = list(inputId = "species", title = "Species:")
)
)
),
mainPanel(DTOutput("resulting_table"))
)
)
server <- function(input, output, session) {
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = starwars_species_hair,
vars = c("hair_color", "species")
)
output$resulting_table <- renderDT({
req(res_mod)
datatable(res_mod())
})
}
shinyApp(ui, server)
We can access selected values inside a reactive/observer by:
observe({
input[["my-filters-hair_color"]]
input[["my-filters-species"]]
)}
I'm trying to copy the table output to the clipboard on a click of a button. I tried looking into the rclipboard package, but it doesn't appear to be able to copy output, in my limited understanding.
I added an actionButton with an icon to the screenshot to show what I'm trying to achieve. Right now the button doesn't do anything.
Code:
library(shiny)
library(dplyr)
df <- mtcars
one <- function(.data, var, na = TRUE) {
return({
.data %>%
group_by(.data[[var]]) %>%
filter(!is.na(.data[[var]])) %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
}
ui <- fluidPage(
selectInput("var", label = "Select Variable", choices = c("", names(df))),
tableOutput("value")
)
server <- function(input, output) {
output$value <- renderTable({
if(input$var != '') {
data <- df %>% one(input$var, na = input$check)
return(data)
}
}, spacing = "xs", bordered = TRUE)
}
shinyApp(ui, server)
Perhaps you can use copy button from DT to copy the whole table. You can also copy only selected rows. Try this
library(shiny)
library(dplyr)
library(DT)
df <- mtcars
one <- function(.data, var, na = TRUE) {
return({
.data %>%
group_by(.data[[var]]) %>%
filter(!is.na(.data[[var]])) %>%
tally() %>%
mutate(`%` = 100*n/sum(n))
})
}
ui <- fluidPage(
selectInput("var", label = "Select Variable", choices = c("", names(df))),
DTOutput("valu", width = "15%")
#tableOutput("value")
)
server <- function(input, output) {
output$valu <- renderDT({
if(input$var != '') {
data <- df %>% one(input$var, na = input$check)
DT::datatable(data,
class = 'cell-border stripe',
rownames = FALSE,
extensions = c("Buttons", "Select"),
selection = 'none',
options =
list(
select = TRUE,
dom = "Bt", ## remove f to remove search ## Brftip
buttons = list(
list(
extend = "copy",
text = 'Copy'#,
#exportOptions = list(modifier = list(selected = TRUE))
)
)
)) %>% formatStyle(
0,
target = "row",
fontWeight = styleEqual(1, "bold")
)
}
}, server = FALSE)
output$value <- renderTable({
if(input$var != '') {
data <- df %>% one(input$var, na = input$check)
return(data)
}
}, spacing = "xs", bordered = TRUE)
}
shinyApp(ui, server)
In the example below, I am trying to produce a box and plot for each group within a dataset, using lapply within a renderUI function. However, some of these groups require an additional filter as they have sub-groupings.
This means creating a selectInput inside the box for those groups only and having the corresponding chart reference that selectInput only.
Here's the reproducible example... my problem is in the lapply loop creating a selectInput with the inputID of paste("selector_",i) and then immediately referencing this in the data to be output inside the corresponding box with input$(what goes here?)
library(shiny)
library(shinydashboard)
library(tidyverse)
library(nycflights13)
library(DT)
data <- planes %>%
select(manufacturer, type, model, year, seats) %>%
unique() %>%
filter(!is.na(year)) %>%
mutate(year = as.character(year))
ui <- dashboardPage(
dashboardHeader(title = "Testing"),
dashboardSidebar(),
dashboardBody(
fluidRow(
column(12, selectInput("type","Type", choices = unique(data$type)),
uiOutput("mytabs"))
)
)
)
server <- function(input, output) {
data_filtered <- reactive({
req(input$type)
data %>%
filter(type == input$type)
})
mfrs <- reactive({
data_filtered() %>%
select(manufacturer) %>%
unique() %>%
pull()
})
output$mytabs = renderUI({
fluidRow(
lapply(mfrs(), function(i) {
dt <- data_filtered() %>%
filter(manufacturer == i) %>%
arrange(year) %>%
select(model, year, seats)
models <- dt %>%
filter(!is.na(model)) %>%
select(model) %>%
unique() %>%
pull()
if(length(models) > 1) {
box(id = paste0('card', i), title = paste(i),
selectInput(inputId = paste0("selector_",i), "Question",
choices = models, selected = models[1]),
DT::datatable(dt[dt$qntext == input$the_one_above],
width = "100%", rownames = F,
options = list(
columnDefs = list(list(width = '40px', targets = "_all"))
))
)
} else {
box(id = paste0('card', i), title = paste(i),
DT::datatable(dt,
width = "100%", rownames = F,
options = list(
columnDefs = list(list(width = '40px', targets = "_all"))
))
)
}
})
)
})
}
shinyApp(ui, server)
As I am not sure what qns means, I have assigned qns to be models. Try this code:
data <- planes %>%
select(manufacturer, type, model, year, seats) %>%
unique() %>%
filter(!is.na(year)) %>%
mutate(year = as.character(year))
ui <- dashboardPage(
dashboardHeader(title = "Testing"),
dashboardSidebar(uiOutput("myqns")),
dashboardBody(
fluidRow(
column(12, selectInput("type","Type", choices = unique(data$type)), uiOutput("mytabs"))
)
)
)
server <- function(input, output) {
data_filtered <- reactive({
req(input$type)
data %>%
filter(type == input$type)
})
mfrs <- reactive({
req(data_filtered())
data_filtered() %>%
select(manufacturer) %>%
unique() %>%
pull()
})
output$myqns <- renderUI({
req(mfrs())
lapply(1:length(mfrs()), function(i) {
dt <- data_filtered() %>%
filter(manufacturer == mfrs()[i]) %>%
arrange(year) %>%
select(model, year, seats)
models <- dt %>%
filter(!is.na(model)) %>%
select(model) %>%
unique() %>%
pull()
qns <- models
selectInput(inputId = paste0("selector_",i), paste("Question",i), choices = as.list(qns), selected = 1)
})
})
output$mytabs = renderUI({
req(mfrs())
fluidRow(
lapply(1:length(mfrs()), function(i) {
req(input[[paste0("selector_",i)]])
dt <- data_filtered() %>%
filter(manufacturer == mfrs()[i]) %>%
arrange(year) %>%
select(model, year, seats)
models <- dt %>%
filter(!is.na(model)) %>%
select(model) %>%
unique() %>%
pull()
qns <- models
if(length(models) > 1) {
box(id = paste0('card', i), title = paste(mfrs()[i]),
# selectInput(inputId = paste0("selector_",i), "Question",
# choices = qns, selected = qns[1]),
DT::datatable(dt[dt$model == input[[paste0("selector_",i)]], ],
width = "100%", rownames = F,
options = list(
columnDefs = list(list(width = '40px', targets = "_all"))
))
)
} else {
box(id = paste0('card', i), title = paste(mfrs()[i]),
DT::datatable(dt,
width = "100%", rownames = F,
options = list(
columnDefs = list(list(width = '40px', targets = "_all"))
))
)
}
})
)
})
}
shinyApp(ui, server)
Answered by the awesome Paul Campbell... using modules.
library(shinydashboard)
library(tidyverse)
library(highcharter)
library(nycflights13)
# Modules ===============================================
# UI and server module for box with chart
box_chart_UI <- function(id, title) {
ns <- NS(id)
box(
title = title, height = 550,
highcharter::highchartOutput(ns("chart"))
)
}
box_chart <- function(input, output, session, df) {
output$chart <- renderHighchart({
validate(need(nrow(df) > 0, "No data"))
hchart(df, "column", hcaes(year, seats))
})
}
# UI and server module for box with chart and filter
box_chart_filter_UI <- function(id, title, filters, filter_lab = "Model") {
ns <- NS(id)
box(
title = title, height = 550,
selectInput(inputId = ns("selector"), label = filter_lab, choices = filters),
highchartOutput(ns("chart"))
)
}
box_chart_filter <- function(input, output, session, df) {
output$chart <- renderHighchart({
req(input$selector)
df_chart <- df %>% filter(model == input$selector)
validate(need(nrow(df_chart) > 0, "No data"))
hchart(df_chart, "column", hcaes(year, seats))
})
}
# Main App ===============================================
# load app data
data <- planes %>%
select(manufacturer, type, model, year, seats) %>%
unique() %>%
filter(!is.na(year)) %>%
mutate(year = as.character(year))
ui <- dashboardPage(
dashboardHeader(title = "Testing"),
dashboardSidebar(),
dashboardBody(
fluidRow(
column(
width = 12,
selectInput("type", "Type", choices = unique(data$type))
)
),
uiOutput("mytabs")
)
)
server <- function(input, output, session) {
data_filtered <- reactive({
req(input$type)
data %>% filter(type == input$type)
})
mfrs <- reactive({
data_filtered() %>%
distinct(manufacturer) %>%
pull()
})
# first load all the UI module functions
output$mytabs <- renderUI({
fluidRow(
lapply(1:length(mfrs()), function(i) {
models <- data_filtered() %>%
filter(manufacturer == mfrs()[i], !is.na(model)) %>%
distinct(model) %>%
pull() %>%
sort()
# depending on how many models, load the correct UI module
if (length(models) > 1) {
box_chart_filter_UI(id = i, title = mfrs()[i], filters = models)
} else {
box_chart_UI(id = i, title = mfrs()[i])
}
})
)
})
# now separately load the module server functions
# need to do this inside an observe due to reactive objects
observe({
lapply(1:length(mfrs()), function(i) {
dt <- data_filtered() %>%
filter(manufacturer == mfrs()[i]) %>%
arrange(year) %>%
select(model, year, seats)
models <- dt %>%
filter(!is.na(model)) %>%
distinct(model) %>%
pull() %>%
sort()
# depending on how many models, load the correct server module
if (length(models) > 1) {
callModule(box_chart_filter, id = i, df = dt)
} else {
callModule(box_chart, id = i, df = dt)
}
})
})
}
shinyApp(ui, server)
This has been bugging me for ages.
I have a function where the first argument either needs to be of the form
function(data~ group_variable) OR of the form function(data, group = data$group_variable).
I have this function running smoothly in the console, but it is integral to my shiny app and it has been bugging me for ages, because both the data and the group are user-selected reactive objects, so it needs to take the form:
function(datasetInput() ~ !!input$group_variable) or some version thereof.
I haven't been able to find any combination of !!s, enquo(), substitute(), as.function(substitute()), etc that will make this work within the shiny app. as.Formula(substitute(data ~ group)) works in the console.
here is as minimal as I can make a reprex:
library(shiny)
library(shinyWidgets)
library(psych)
library(dplyr)
library(gt)
use <- function(name) {
# consider future support for .json?
if (grepl(".csv", name)) {
readr::read_csv(name)
} else if (grepl(".xlsx", name)) {
readxl::read_xlsx(name)
} else if (grepl(".dta", name)) {
haven::read_dta(name)
} else if (grepl(".sav", name)) {
haven::read_spss(name)
} else if (grepl(".rda", name)) {
load(name)
} else {
stop("unknown data type.")
}
}
ui <- fluidPage(
mainPanel(
fileInput("FileInput", "Input Your Data Set"),
helpText("Dataset must be one of: .csv, .sav, .dta, .xlsx, or .rda"),
materialSwitch(
inputId = "ext_desc",
label = "Extended Description",
value = FALSE,
status = "primary"
),
materialSwitch(
inputId = "desc_by_group_bool",
label = "Describe By A Group",
value = FALSE,
status = "primary"
),
varSelectInput(
inputId = "desc_group",
label = "Select A Group",
data = NULL,
width = "400px"
),
gt::gt_output("description")
)
)
server <- function(input,output, session){
datasetInput <- reactive({
infile <- input$FileInput
if (is.null(infile))
return(NULL)
dat<-use(infile$datapath)
names(dat) <- gsub(" ", "_", names(dat), fixed = TRUE)
return(dat)
})
observeEvent(datasetInput(), {
updateVarSelectInput(session, "desc_group", data = datasetInput())
})
desc <- reactive({
req(datasetInput())
if (input$desc_by_group_bool == FALSE) {
datasetInput() %>%
#select_if(is_numeric) %>%
psych::describe(., fast = !(input$ext_desc),
omit = TRUE) %>%
add_rownames(var = "Variable") %>%
dplyr::select(-c(vars)) %>%
dplyr::mutate(dplyr::across(is.numeric, round, 2)) %>%
gt::gt() %>%
gt::tab_options(
column_labels.font.size = "small",
table.font.size = "small",
row_group.font.size = "small",
data_row.padding = px(3)
) %>%
gt::tab_header(title = paste0("Data Description"))
} else {
# datasetInput() %>%
# select_if(is.numeric) %>%
psych::describeBy( datasetInput() ~ !!input$desc_group,
# here we get "invalid argument type" error
fast = !(input$ext_desc),
mat = TRUE) %>%
tibble::rownames_to_column() %>%
select(-c(item, vars)) %>%
dplyr::mutate(dplyr::across(is.numeric, round, 2)) %>%
arrange(group1) %>%
group_by(group1) %>%
gt() %>%
gt::tab_options(
column_labels.font.size = "small",
table.font.size = "small",
row_group.font.size = "small",
data_row.padding = px(3)
) %>%
tab_header(title = paste0("Data Description") ,
subtitle = paste0("Grouped by: ", input$desc_group)
)
}
})
output$description = gt::render_gt(desc())
}
shinyApp(ui = ui, server = server)
The line causing the error--and the source of my question, is, forgive me, line 85 above.
There are various ways we can solve this. One way would be to use [[]] to subset the specific column. So change the describeBy line to :
psych::describeBy( datasetInput(), group = datasetInput()[[input$desc_group]]
Also add where in dplyr::across
dplyr::mutate(dplyr::across(where(is.numeric), round, 2))