Hello!
First of all: anybody could tell me how to paste code snippets in posts? Mine seem to behave randomly... The only way I figured out is putting 4 spaces in each row - but there must be a simpler way.
I have a simple shiny app. First, I generated 2 csv files in my working directory:
write.csv(data.frame(a = 1:4, b = 2:5), "x.csv", row.names = F)
write.csv(data.frame(a = 1:4, c = 11:14), "y.csv", row.names = F)
In my app, I want the user to:
- read in 2 files (x.csv and y.csv) and...
- Click on the button 'Run'!
- After that I want server.R to write out 2 csv files - but also to print out certain messages for the user to see.
My code below works, but currently the messages for the user look very ugly and each is sitting on a dull gray background.
Two questions:
- Is my method the only method to print messages for the user? Or maybe there is a more elegant one?
- How could I modify the gray background, font size, color, etc?
Thank you so much!
library(shiny)
library(shinyjs)
# ui code:
ui <- fluidPage(
useShinyjs(),
br(),
# User should upload file x.csv here:
fileInput("file_x", label = h5("Upload file 'x.csv'!")),
br(),
# User should upload file y.csv here:
fileInput("file_y", label = h5("Upload file 'y.csv'!")),
br(),
# Users clicks the button:
actionButton("do_it", "Run!"),
br(),
hidden(p("First, please upload one of the 2 files above!",
id = "p_nofiles",
style = "font-weight:bold;color:red;")),
br(),
verbatimTextOutput("message_1"),
br(),
verbatimTextOutput("message_2"),
br(),
verbatimTextOutput("message_3")
)
# server code:
server <- function(input, output, session) {
observeEvent(input$do_it, {
# If there file_x input is NULL, show the message in p_nofile
if (is.null(input$file_x) | is.null(input$file_y)) {
shinyjs::show("p_nofiles")
} else {
# if both files are selected, hide the p_nofiles message
shinyjs::hide("p_nofiles")
# Check my button's value:
output$print_action <- renderPrint({input$do_it})
# Read in file x_csv:
infileX <- input$file_x
if (is.null(infileX)) {
return(NULL)
}
x <- read.csv(infileX$datapath)
# Read in file y_csv:
infileY <- input$file_y
if (is.null(infileY)) {
return(NULL)
}
y <- read.csv(infileY$datapath)
#-------------------------------------------------------------------------------------------
# MESSAGES I WANT THE USER TO SEE:
# MESSAGE 1 - always there: What names do x and y have in common?
mes1 <- paste0("x and y have these columns in common: ",
intersect(names(x), names(y)), "\n")
output$message_1 <- renderText({mes1})
# MESSAGE 2 - with 2 alternative texts: Do x and y have the same number of rows?
if (nrow(x) == nrow(y)) {
mes2 <- "x and y have the same number of rows!\n"
} else {
mes2 <- "x has a different number of rows than y\n"
}
output$message_2 <- renderText({mes2})
# MESSAGE 3 - to be printed only under one condition:
# Do x and y have a different number of columns? Print only it's different, otherwise - nothing
if (ncol(x) != ncol(y)) {
mes3 <- "x and y do NOT have the same number of columns!\n"
output$message_3 <- renderText({mes3})
} else {output$message_3 <- renderText({NULL})}
#-------------------------------------------------------------------------------------------
# Writing out the same file x - but under a different name:
filenameX <- paste0("x", input$do_it, ".csv")
write.csv(x, file = filenameX, row.names = FALSE)
# Writing out the same file y - but under a different name:
filenameY <- paste0("y", input$do_it, ".csv")
write.csv(y, file = filenameY, row.names = FALSE)
}
})
}
shinyApp(ui, server)