I am trying to create a Shiny app where a user can upload a csv file, input a numeric value, add the numeric value to a specific column of data in the csv, then save the raw + calculated data in a table. I generated a simplified Shiny script below using a simple csv file.
When I try and run the app, I get the error:
Problem with mutate() input sum.
[31mx[39m non-numeric argument to binary operator
[34mi[39m Input sum is A + C.
I tried looking up some examples of how to fix this, but was unable to find something that utilized eventReactive() to keep the data table updated with the new calculated data. Any help is greatly appreciated.
library(shiny)
library(dplyr)
ui <- fluidPage(
# Application title
titlePanel("Test"),
# Show a plot of the generated distribution
mainPanel(
fileInput(
inputId = "csvFile",
label = "Upload csv file",
accept = c(".csv")),
uiOutput("C"),
uiOutput("D"),
tableOutput("modifiedData")
)
)
server <- function(input, output) {
output$C <- renderUI(
{numericInput("C", "Variable C", 0)}
)
output$D <- renderUI(
{numericInput("D", "Variable D", 0)}
)
userData <- eventReactive(input$csvFile,
{
req(input$csvFile)
raw_df <- read.csv(input$csvFile$datapath)
calc_df <- raw_df %>%
mutate(sum = A + C)
})
output$modifiedData <- renderTable({userData()})
}
shinyApp(ui = ui, server = server)
You should be using the reactive variable input$C. Also, you should make the eventReactive dependent on input$C. Try this
ui <- fluidPage(
# Application title
titlePanel("Test"),
# Show a plot of the generated distribution
mainPanel(
fileInput(
inputId = "csvFile",
label = "Upload csv file",
accept = c(".csv")),
uiOutput("C"),
uiOutput("D"),
tableOutput("modifiedData")
)
)
server <- function(input, output) {
output$C <- renderUI(
{numericInput("C", "Variable C", 0)}
)
output$D <- renderUI(
{numericInput("D", "Variable D", 0)}
)
userData <- eventReactive(list(input$csvFile, input$C),
{
req(input$csvFile)
raw_df <- read.csv(input$csvFile$datapath)
calc_df <- raw_df %>%
mutate(sum = A + input$C)
})
output$modifiedData <- renderTable({userData()})
}
shinyApp(ui = ui, server = server)
Related
I have an app that reads data (it can be further developed to be able to read excel,csv data) and then based on unique values by every columns(user input) i can filter my data but the problem here is that sometimes the list of values is large .is it possible to be able to just write some letters or numbers (depends on nature of column)in the user input to get only values that match what we write there exactly like in pivot excel.below is my code without this characteristic.
library(shiny)
library(dplyr)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
selectInput("df",
label="Upload files here",
choices = list.files("C:/Users/zbensmid/Documents")),
uiOutput('choose_cyl'),
uiOutput('choose_vs'),
uiOutput('choose_am')
),
mainPanel(
tableOutput("table")
)
)
))
server <- shinyServer(function(input, output) {
mydata<-reactive({
fread(input$df)
})
output$choose_cyl<-renderUI({selectInput("cyl", "cyl", unique(mydata()$cyl), multiple = TRUE)})
output$choose_vs<- renderUI({selectInput("vs", "vs", unique(mydata()$vs), multiple = TRUE)})
output$choose_am<- renderUI({selectInput("am", "am", unique(mydata()$am), multiple = TRUE)})
output$table <- renderTable({
df<-mydata()
cyl_sel <- if (is.null(input$cyl)) unique(mydata()$cyl) else as.numeric(input$cyl)
vs_sel <- if (is.null(input$vs)) unique(mydata()$vs) else as.numeric(input$vs)
am_sel <- if (is.null(input$am)) unique(mydata()$am) else as.numeric(input$am)
filter(df, cyl %in% cyl_sel, vs %in% vs_sel, am %in% am_sel)
})
})
shinyApp(ui = ui, server = server)
Below is the data you can put it as excel file.
I'm trying to create a Shiny application that has ~100 user inputs, some of which may go untouched. I think that I could make a reactive dataframe within the app by writing input$user_input_1, input$user_input_2, etc. 100 times to call each input individually. Instead, I'm wondering if there is a way to programmatically generate that list of inputs using a concatenating function and then evaluate those inputs as if I had typed input$user_input_1. When I run the following code, however, I get a message telling me that Error: object 'input' not found.
My end goal is to be able to take these user inputs and use them in some behind-the-scenes transformations. If my current set up isn't the most efficient way to capture a large number of inputs, please let me know, but at the very least I'd like to understand what isn't working here.
I'd appreciate some help here. Thanks.
library(shiny)
library(tidyverse)
input_tbl <- tibble(inputs = c("x", "y", "z"))
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput(
inputId = "number_x",
label = "Input X",
value = 30
),
numericInput(
inputId = "number_y",
label = "Input Y",
value = 60
),
numericInput(
inputId = "number_z",
label = "Input Z",
value = 90
)
),
mainPanel(
verbatimTextOutput("table")
)
)
)
server <- function(input, output) {
value_tbl <- eventReactive(
eventExpr = input$number_x,
valueExpr = {
tibble(
inputs = input_tbl %>% pull(),
values = input_tbl %>%
pull() %>%
modify(~ str_c("input$number_", .x)) %>%
map(~ parse(text = .x)) %>%
map(eval)
)
})
output$table <- renderPrint(value_tbl())
}
shinyApp(ui = ui, server = server)
If I got you right you could achieve your desired result with purrr::map_df in one line of code like so:
server <- function(input, output) {
value_tbl <- eventReactive(
eventExpr = input$number_x,
valueExpr = {
map_df(input_tbl$inputs, ~ data.frame(inputs = .x, values = input[[paste0("number_", .x)]]))
})
output$table <- renderPrint(value_tbl())
}
Turns out I was using the wrong evaluation function.
Instead of map(eval), I need to use map(eval.parent).
I know this question has been posted a few times but this is my first time developing something i Shiny and I am getting confused with a couple different things. One of them is inputting the data frame correctly and using it in the output functions.
My only goals right now is to:
Display the head or complete dataframe depending on user choice
I have a binary column called status (status being Pass or Fail). I want to group by dates to count the status (any one would do) and plot it.
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(readxl)
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Data Quality Result Monitoring"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx")
),
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
radioButtons("disp", "Display",
choices = c(Head = "head",
All = "all"),
selected = "head")
),
# Show a plot of the generated distribution
mainPanel(
#plotOutput("linechart"),
h4("Observations"),
tableOutput("contents")
)
)
# Define server logic required to draw a histogram'
library(ggplot2)
server <- function(input, output) {
df <- reactive({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
df <- read_xlsx(inFile$datapath, sheet = 1)
return(inFile)})
output$linechart <- renderPlot({
ndf() <- group_by(df,Execution_Date) %>% summarize( count = n() )
ggplot(ndf()) + geom_bar(aes(x=week,y=count),stat="identity")
})
output$contents <- renderTable({
# input$file1 will be NULL initially. After the user selects
# and uploads a file, head of that data file by default,
# or all rows if selected, will be shown.
dataset() <- df
if(input$disp == "head") {
return(head(dataset()))
}
else {
return(dataset())
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
dataset() <- df
This is where you get the error:
"Error in <-: invalid (NULL) left side of assignment"
You can not assign a value to a reactive expression. It works the other way round:
dataset <- df()
Play around with this by using the print function.
Another error in your code is this:
df <- read_xlsx(inFile$datapath, sheet = 1)
return(inFile)
You return the wrong variable, you want to return the df.
Here is the code which should work for you:
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(readxl)
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Data Quality Result Monitoring"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose xlsx file',
accept = c(".xlsx")
),
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
radioButtons("disp", "Display",
choices = c(Head = "head",
All = "all"),
selected = "head")
),
# Show a plot of the generated distribution
mainPanel(
#plotOutput("linechart"),
h4("Observations"),
tableOutput("contents")
)
)
# Define server logic required to draw a histogram'
library(ggplot2)
server <- function(input, output) {
df <- reactive({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
df <- read_xlsx(inFile$datapath, sheet = 1)
df
})
output$linechart <- renderPlot({
ndf <- group_by(df(),Execution_Date) %>% summarize( count = n() )
ggplot(ndf + geom_bar(aes(x=week,y=count),stat="identity"))
})
output$contents <- renderTable({
# input$file1 will be NULL initially. After the user selects
# and uploads a file, head of that data file by default,
# or all rows if selected, will be shown.
dataset <- df()
if(input$disp == "head") {
return(head(dataset))
}
else {
return(dataset)
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
I also recommend that you implement a check for structure and names in your code.
This is due to ndf() <- group_by(df,Execution_Date) %>% summarize( count = n() )
ndf() is NULL function that does not exist.
df is a reactive and you use it with df() instead of df, meaning that code is evaluated each time the reactivity changes.
I am working on a simple app that is supposed to ask for 1 (or more) unstructured text files, given by the user with fileInput. These files have all the same structure.
The idea is to make the cleaning/extraction on the background and give back the clean data to the user (ideally into a table).
I am fairly new using Shiny and the examples I have found basically indicate how to proceed when the file input is already in a clean and structured way.
Here is a simplified code that illustrates what I have done so far:
library(shiny)
shinyUI(fluidPage(
titlePanel(title = h2("Title", align = "left")),
sidebarLayout(position = "left",
sidebarPanel(h3("Data management window", align = "center"),
fileInput(inputId = "file_1",
label = "Select file 1")
),
mainPanel(
uiOutput(outputId = "tb")
)
)))
And here the server side:
shinyServer(function(input, output) {
input_file_1 <- reactive({
if(is.null(input$file_1)){
return("!! No data loaded !!")
}
readLines(input$file_1$datapath)
})
output$data_1 <- renderText({
fileText_1 <- paste(input_file_1(), collapse = "\n")
})
output$tb <- renderUI({
tabsetPanel(
tabPanel("Window 1",
br(),
tags$div(
tags$p("Summary infos : "),
tags$ul(
tags$li("Date calculation : ", Sys.Date()),
tags$li("Info 1: "),
tags$li("Info 2 : "),
tags$li("Info 3 : "),
br(),
verbatimTextOutput("data_1"))
))
)
})
})
At this stage I have managed to render the text of the file into the app. What I would like to do is to show in tabPanel some results obtained from the data extracted from the text file, like in the case of Sys.Date() but using values from the input file.
Do you have any ideas on how to proceed? Hope my question makes sense.
Your question is still too general, please more specific. But here is something to get you started. Using your server file and the iris dataset to make it easier, you can use the renderText() expression to extract the summary of one of your variable. And then you just add textOutput() expression in your tags$li("Info 1: ") argument.
Following a comment from OP, you could add a selectInput() that could help you pick one variable you want to summarise or extract information from. The code work as it is. Just replace iris by the file you will be loading.
ui = fluidPage(
titlePanel(title = h2("Title", align = "left")),
sidebarLayout(position = "left",
sidebarPanel(h3("Data management window", align = "center"),
fileInput(inputId = "file_1",
label = "Select file 1"),
uiOutput("Variable")
),
mainPanel(
uiOutput(outputId = "tb")
)
))
server = function(input, output) {
input_file_1 <- reactive({
if(is.null(input$file_1)){
return("!! No data loaded !!")
}
readLines(input$file_1$datapath)
})
output$data_1 <- renderText({
fileText_1 <- paste(input_file_1(), collapse = "\n")
})
output$Variable <- renderUI({
obj2 <- iris #replace by input_file_1()
selectInput("Variable", "Choose a variable", as.list(colnames(obj2)), multiple = FALSE)
})
output$summary1 <- renderPrint({
sub <- iris %>% select(input$Variable) #replace iris
a <- max(sub)
a
})
output$tb <- renderUI({
tabsetPanel(
tabPanel("Window 1",
br(),
tags$div(
tags$p("Summary infos : "),
tags$ul(
tags$li("Date calculation : ", Sys.Date()),
tags$li("Info 1: ", textOutput("summary1")),
tags$li("Info 2 : "),
tags$li("Info 3 : "),
br(),
verbatimTextOutput("data_1"))
))
)
})
}
I am trying to print dataset values in shiny web app. But I am only able to print data set name using below code. How can I print dataset values?
library(MASS)
library(shinythemes)
library(shiny)
library(ggplot2)
mass.tmp <- data(package = "MASS")[3]
mass.datasets <- as.vector(mass.tmp$results[,3])
ui <- fluidPage(
theme = shinytheme("superhero"),
titlePanel("Linear Regression Modelling"),
sidebarLayout(
sidebarPanel(
selectInput("dsname", "Dataset:",choices = c(mass.datasets))
,
uiOutput("x_axis")
# ,
# textOutput("txt"),
# tableOutput("tab")
),
mainPanel(
tags$br(),
tags$br()
)
)
)
server <- function(input, output) {
num_ds <- function(ds)
{
nums <- sapply(ds,is.numeric)
num_ds <- ds[,nums]
return(num_ds)
}
ds_ext <- reactive({ num_ds(input$dsname) })
output$x_axis <- renderUI({
col_opts <- get(ds_ext())
selectInput("x_axis2", "Independent Variable:", choices = names(col_opts))
})
}
shinyApp(ui = ui, server = server)
Actually I am trying to solve error in above code "Incorrect number of dimensions". I have written function which would return data frame with only numeric variables so that I can analyze. But getting error in line I guess where I am creating object x_axis. pls help.