I would like to read and process a raster file, and after that, I would like to save the result using shinySaveButton
the read and process steps are functioning well, but still, I can not save the output of the process!
library(shiny)
library(raster)
library(rgdal)
library(shinyFiles)
file1<- "D:\\dgm_test.tif"
ui <- fluidPage(
titlePanel(p("Dyke extraction tool", style = "color:#3474A7")),
sidebarLayout(
sidebarPanel(
fileInput(inputId = "dgm", accept = "tif",
label = "Choose a raster"),
actionButton(inputId = "click",
label = "Update"),
shinySaveButton("save", "Save file", "Save file as ...", filetype= ".tif")
# the desired format that I want at the end is .tif
),
mainPanel(
plotOutput("plot1"),
plotOutput("plot2")
)
)
)
server <- function(input, output,session) {
data1<- reactive({
req(input$dgm)
raster::raster(input$dgm$datapath)
})
observeEvent(input$click, {
output$plot1<- renderPlot(
{plot(data1())
}
)
output$plot2<- renderPlot(
{plot(aggregate(data1(), fact=100, fun=mean, expand=TRUE))# I want to enable
the user to save this output as a raster(tif format) ??
}
)
}
)
}
shinyApp(ui = ui, server = server)
could you please assist me to figure out how I can do that?
Related
library(shiny)
library(ggplot2)
report.Rmd
date: "2023-01-15"
output: html_document
params:
x_column: "Sepal.Width"
y_column: "Sepal.Length"
library(ggplot2)
ggplot(data = iris)+
aes_string(params$x_column,params$y_column)+
geom_point()
shiny app
library(shiny)
library(ggplot)
library(rmarkdown)
ui <- fluidPage(
titlePanel("Iris Data"),
sidebarLayout(
sidebarPanel(
selectizeInput("xcol",
"Choose X Axis",
choices = names(iris)
),
selectizeInput("ycol",
"Choose Y Axis",
choices = names(iris)
),
downloadButton("project", "Download plot")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output) {
filename = "report.html
output$plot <- renderPlot({
ggplot(data=iris)+
aes_string(x=input$xcol, y=input$ycol)+
geom_point()
})
output$print <- downloadHandler({
filename="report.html"
content = function(file) {
rmarkdown::render("report.Rmd",
output_file=file, params=list(x_column = input$xcol,
y_column = input$ycol))
}
})
}
I can't get the app to render my rmarkdown file. I can't seem to see the mistake. report.Rmd is in my working directory. I can get it to work outside of shiny, but in shiny it says there is an error and the content is missing without a default value
There are two issues with your code. First, you used the id Project for the downloadButton but named the output print. Second, the API of downloadHandler is a bit different from reactive or renderXXX, i.e. you have to pass filename and content as arguments.
Note: Also it's good practice to copy the report file to a temporary directory before processing it and to evaluate the document in a child of the global environment. See Generating downloadable reports. As an example where missing the last step fails to render an Rmd correctly see this post. Finally, note that aes_string is deprecated since ggplot2 3.4.0. Instead it's recommended to use the .data pro-noun as I do in the code below.
library(shiny)
library(ggplot2)
ui <- fluidPage(
titlePanel("Iris Data"),
sidebarLayout(
sidebarPanel(
selectizeInput("xcol",
"Choose X Axis",
choices = names(iris)
),
selectizeInput("ycol",
"Choose Y Axis",
choices = names(iris)
),
downloadButton("print", "Download plot")
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output) {
output$plot <- renderPlot({
ggplot(data = iris) +
aes(.data[[params$x_column]], .data[[params$y_column]]) +
geom_point()
})
output$print <- downloadHandler(
filename = "report.html",
content = function(file) {
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
rmarkdown::render(tempReport,
output_file = file,
params = list(
x_column = input$xcol,
y_column = input$ycol
),
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:5776
#> Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
#> ℹ Please use tidy evaluation ideoms with `aes()`
I am trying to run the following code, but keep getting this error:
Error in readLines: 'con' is not a connection
The following is my program:
library(shiny)
library(shinyFiles)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
width = 2,
fileInput("file1", "Choose the first HTML File", accept = ".html")
),
mainPanel(
p("File Name"),
verbatimTextOutput("file_name"),
htmlOutput(outputId = 'result')
)
)
)
server <- function(input, output) {
file <- reactive({input$file1})
req(file)
if(is.null( reactive(input$file1$datapath))) return(NULL)
rawHTML <- reactive(paste(readLines(input$file1$datapath), collapse="\n"))
output$file_name <- renderText({
print(rawHTML)
})
output$result <- renderUI({
getPage<-function() {
return(includeHTML( input$file1$datapath))
}
output$inc<-renderUI({getPage()})
})
}
runApp(list(ui = ui, server = server), launch.browser =T)
I want to read the html code from an external file, and save the code as a string. Is there a solution for this?
I have been trying to merge data with another data set based on input from a drop down. I have just started learning R and have run into some problems and want to know if there is a better way of going about this.
I am getting an error that it cannot coerce class c(ReactiveExpr, reactive) to a data frame.
library(shiny)
library(plyr)
library(dplyr)
library(xlsx)
server <- function(input, output){
annotation1 <- read.xlsx("input1.xlsx", sheetIndex = 1, header = TRUE)
annotation2 <- read.xlsx("input2.xlsx", sheetIndex = 1, header = TRUE)
data_input <- eventReactive(input$userfile, {
df <- read.xlsx(input$userfile$datapath, sheetIndex = 1, header = TRUE)
})
output$data_input <- renderTable(data_input())
output$annotation <- renderTable(annotation)
data_species <- c("Set1", "Set2")
# Drop-down selection box for which data set
output$choose_species <- renderUI ({
selectInput("species", "Species", as.list(data_species))
})
output$mergeddata <- renderTable({
if(input$species == "Set1"){
eventReactive("Set1",({left_join(data_input(), annotation1, by = c("Column1" = "Column1"))}))
}
else if(input$species == "Set2"){
eventReactive("Set2",({left_join(data_input(), annotation2, by = c("Column1" = "Column1"))}))
}
})
}
ui <- fluidPage(
titlePanel(
div("Test")
),
sidebarLayout(
sidebarPanel(
fileInput("userfile", "Input File", multiple =FALSE,
buttonLabel = "Browse Files", placeholder = "Select File"),
uiOutput("choose_species"),
uiOutput("choose_annotations"),
),
mainPanel(
tableOutput("mergeddata"),
br()
),
),
)
# Run the application
shinyApp(ui = ui, server = server)
In general, you approach seems ok. The error you get is from the line
eventReactive("Set1",({left_join(data_input(), annotation1, by = c("Column1" = "Column1"))}))
An eventReactive returns an (unevaluated) reactive expression which you try to render as data.frame with renderTable. To circumvent this, you could use:
eventReactive("Set1",({left_join(data_input(), annotation1, by = c("Column1" = "Column1"))}))()
However, here you don't need eventReactive, because your reactivity comes from input$species (you want to change the table output based on this input). Therefore, you can just use:
output$mergeddata <- renderTable({
if(input$species == "Set1"){
merge_data <- annotation1
} else {
merge_data <- annotation2
}
left_join(data_input(), merge_data, by = c("Column1"))
})
I have a Shiny code as like this
library(datasets)
ui <-fluidPage(
titlePanel("Telephones by region"),
sidebarLayout(
sidebarPanel(
selectInput("region", "Region:",
choices=colnames(WorldPhones)), checkboxInput(inputId = "Adv",
label = strong("Advanced"),
value = FALSE),fileInput("file1", "Choose CSV File",
multiple = FALSE,accept = c("text/csv", "text/comma-separated-values,text/plain", ".csv")),
hr(),
helpText("Data from AT&T (1961) The World's Telephones.")),
mainPanel(
plotOutput("phonePlot") )))
server <- function(input, output) {
output$phonePlot <- renderPlot({
barplot(WorldPhones[,input$region]*1000,
main=input$region,
ylab="Number of Telephones",
xlab="Year")})}
shinyApp(ui, server)
I need to implement following modifications
How to disable/enable selectInput and fileInput upon the selection of Advanced checkboxInput. If user choose advanced, the selectInput must be disable (vice versa)
How to use if function for fileInput from user input (Asia,Africa….ect one per line )
To enable/disable the inputs you can use package shinyjs.
Something like this should work:
library(datasets)
library(shiny)
ui <-fluidPage(
shinyjs::useShinyjs(),
titlePanel("Telephones by region"),
sidebarLayout(
sidebarPanel(
selectInput("region", "Region:",
choices=colnames(WorldPhones)),
checkboxInput(inputId = "Adv",
label = strong("Advanced"),
value = FALSE),
fileInput("file1", "Choose CSV File",
multiple = FALSE,accept = c("text/csv", "text/comma-separated-values,text/plain", ".csv")),
hr(),
helpText("Data from AT&T (1961) The World's Telephones.")),
mainPanel(
plotOutput("phonePlot") )))
server <- function(input, output) {
observe({
if((input$Adv == TRUE)) {
shinyjs::disable("region")
shinyjs::disable("file1")
} else {
shinyjs::enable("region")
shinyjs::enable("file1")
}
})
output$phonePlot <- renderPlot({
barplot(WorldPhones[,input$region]*1000,
main=input$region,
ylab="Number of Telephones",
xlab="Year")})}
shinyApp(ui, server)
I was wondering if it is possible to save DT table content together with some additional information which is not part of the data frame/table like app version number, date of execution, sliderInput value etc.
Thank you!
Reprex below:
library(shiny)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "range", "Set range", 1, 10, 5, 1)
),
mainPanel(
DT::dataTableOutput("table")
)
)
)
server <- function(input, output) {
dfr <- data.frame(var1 <- c(1,2,3),
var2 <- c(11, 22, 33))
output$table <- DT::renderDataTable(
datatable(dfr, extensions = 'Buttons',
class="cell-border stripe",
rownames = FALSE, colnames = c("var1", "var2"),
options = list(dom = "Blfrtip",
buttond = list("copy", list(extend = "collection",
buttons = c("csv", "excel", "pdf"),
text = "Download")), pageLength=10, autoWidth = TRUE,
searchHighlight = TRUE, filter = "top"))
)
}
shinyApp(ui = ui, server = server)
You could save the contents of the data frame and the other information in a list and then save the list.
Or, any R object can have attributes which are completely arbitrary and under your control. You could set attributes of the data frame to record the information you want.
Personally, I'd use the list approach, purely because I don't like attributes.
Here's a suggestion in response to OP's request below.
library(shiny)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "range", "Set range", 1, 10, 5, 1),
actionButton("saveRds", "Save to Rds"),
actionButton("loadRds", "Load from Rds")
),
mainPanel(
DT::dataTableOutput("table"),
wellPanel(h4("Current data"), verbatimTextOutput("text")),
wellPanel(h4("File data"), verbatimTextOutput("loadedData"))
)
)
)
server <- function(input, output) {
dfr <- data.frame(var1 <- c(1,2,3),
var2 <- c(11, 22, 33))
output$table <- DT::renderDataTable(
datatable(dfr, extensions = 'Buttons',
class="cell-border stripe",
rownames = FALSE, colnames = c("var1", "var2"),
options = list(dom = "Blfrtip",
buttond = list("copy", list(extend = "collection",
buttons = c("csv", "excel", "pdf"),
text = "Download")), pageLength=10, autoWidth = TRUE,
searchHighlight = TRUE, filter = "top"))
)
listInfo <- reactive({
list("data"=dfr, "version"="WebApp Version 1.0", "runDate"=date(), "sliderValue"=input$range)
})
output$text <- renderPrint({
listInfo()
})
observeEvent(input$saveRds, {
saveRDS(listInfo(), "data.Rds")
})
fileData <- reactive({
req(input$loadRds)
readRDS("data.Rds")
})
output$loadedData <- renderPrint({
fileData()
})
}
shinyApp(ui = ui, server = server)
The way you implement "save to file" will depend on the file format: Excel files will clearly have different requirements to PDF files, for example. As a minimum effort demonstation, I've created "Save to Rds" and "Load from RDS" buttons in the sidebar and added a verbatimTextOutput to display the contents of the file when it's loaded. [I'm not sufficiently familiar with DT to know how to add the buttons in the table toolbar.]
OP's effort was pretty close: it's just that writing a list to CSV file takes a little more effort than just calling write.csv...