Replacing accents in R/Shiny - r

My problem relates to translation of accented characters in R/Shiny - I tried to employ the solution discussed here but ran into a frustrating exception:
Within RStudio; if I highlight all lines of the code below and then press Ctrl+Enter (Run-Selected-Lines) I get the expected output of "ooo".
However if I press 'Run App' (as part of a project) I instead get "ǒoo" - i.e. the first character doesn't get mapped.
library(shiny)
ui <- fluidPage()
server <- function(input, output) {
charactermap = list('ǒ'='o', 'ô'='o', 'ø'='o')
removeaccents <- function(x) {
corrected <- chartr(paste(names(charactermap), collapse=''),
paste(charactermap, collapse=''),
x)
return(corrected)
}
print(removeaccents("ǒôø"))
}
# Run the application
shinyApp(ui = ui, server = server)
This seems to happen with only a small number of characters I am interested in - any ideas why this may be happening and how to fix it please???

Related

Can I have if statements that operate on UI that is triggered at the same time?

I'm trying to build a simple app with two modes. The user can leave 'non-interactive-mode' by flicking a switch. This generates some new UI elements, and produces a result based on the values in the UI element.
For some operations this works fine, but my if statements throw Warnings at the first time I run the code (Warning: Error in if: argument is of length zero). I think I understand why this is happening (the input doesn't exist the first time the code reads the if block), but can it be worked around in a simple way?
MWE below:
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
materialSwitch(inputId = "interactive", label = "Interactive?",value=FALSE),
uiOutput("on_interactive_only"),
uiOutput("result_output")
)
server <- function(input, output) {
# Non-interactive Result
output$result_output <- renderUI(if(!input$interactive){
(renderTable(data.frame('dummy'=1:3)))})
# If interactive we need another UI element
output$on_interactive_only <- renderUI(if(input$interactive){
numericInput("value_to_specify",'Which Number?',5)})
# And now we need to react to that value
output$result_output <- renderUI(if(input$interactive){
if(input$value_to_specify > 3){
(renderTable(data.frame('dummy'=input$value_to_specify)))}})
}
shinyApp(ui = ui, server = server)

Rstudio Connect Shiny dashboard only shows plot if table is visible

I want to have a Shiny dashboard on Rstudio Connect where data is read from my companies data store via JDBC, and then plotted. Ultimately the user would be able to give some parameters and the appropriate output would be displayed.
What I've discovered is that if I show a table of the data and the plot, everything works out fine. However, if I do not display the table I get an error:
Error: An error has occurred. Check your logs or contact the app author for clarification.
The line in the log files related to the error is not meaningful to me, but appears to be java related (and so maybe related to the JDBC connection):
Warning: Error in .jcheck: Java Exception <no description because toString() failed>
.jcall(conn#jc, "Ljava/sql/Statement;", "createStatement")
new("jobjRef", jobj = <pointer: 0x55cbc9a35608>, jclass = "java/lang/Throwable")
What works?
Here's as minimum a reproducible example as I could get. I appreciate that the architecture is internal to my company, so it won't run for others, but I think it can be helpful. The below code works:
# app.R
library(RJDBC)
library(shiny)
getconnection <- function(){
ORACLE_JAR <- '/usr/lib/oracle/21/client64/lib/ojdbc8.jar'
db_host = "db_host.company.information:1521"
drv <- RJDBC::JDBC("oracle.jdbc.OracleDriver",
ORACLE_JAR,
identifier.quote="`")
sid <- "sid.prd.tns"
url <- paste("jdbc:oracle:thin:#/",
db_host,
sid, sep = '/')
connection<-dbConnect(drv,
url,
user='****', # anonymised for stack overflow
password='****',
believeNRows=FALSE )
return(connection)
}
ui <- fluidPage(
titlePanel("MinRepEx"),
tableOutput('result'),
plotOutput('plot')
)
server <- function(input, output) {
conn <- getconnection()
mydata <- reactive({query_result(conn)})
output$result <- renderTable(head(mydata()))
output$result <- NULL
myplot <- reactive({plot(OBS_VALUE ~ OBS_DATE, data = mydata())})
output$plot <-renderPlot({myplot()})
}
shinyApp(ui = ui, server = server)
When I deploy this, as I say it works:
What doesn't work?
If I remove the lines related to result, i.e. the table output things stop working:
## Everyhing above this line is kept unchanged
ui <- fluidPage(
titlePanel("MinRepEx"),
# tableOutput('result'),
plotOutput('plot')
)
server <- function(input, output) {
conn <- getconnection()
mydata <- reactive({query_result(conn)})
# output$result <- renderTable(head(mydata()))
myplot <- reactive({plot(OBS_VALUE ~ OBS_DATE, data = mydata())})
output$plot <-renderPlot({myplot()})
}
shinyApp(ui = ui, server = server)
which leads to:
Possible solutions that need tweeking:
The code works as intended on my machine it does not work when I ship it to RStudio Connect.
The code is a minimised version of the code where there is a need for query_result to be a reactive function, so I can't take it out of the reactive world. However, if I do, I can display the chart on its own. `
Likewise, if I open the connection conn inside mydata it will generate the image. However opening the connection each time is very slow. If there was someway to check if a connection was open and if not open one, or to make the connection visible inside mydata?
What else have I tried?
I've tried a few other things that might help inform about the solution:
If I just do renderTable, there are no problems (except that I do't have the chart I want).
If I change the order of plotOutput and tableOutput in the UI, the table and plot appear
If I change the order of renderTable and renderPlot in the server, neither table nor plot are produced and I have the same error message in the logs twice.
If I introduce a Sys.sleep(60) command to myplot, it doesn't fix the issue
I have put a the line data <- mydata() inside the renderPlot({...}) before myplot()
The above 'possible solutions' might yield something, but rather frustratingly, I would like to know why the connection remains visible if I show the table or the table and plot, but not the plot on its own. Likewise, the code works without this issue locally, but not remotely. It would be interesting to understand why.

R: Data Frame launching manually works well, in shiny is incomplete

I webscraped 2 tables (A and B). Then I merge them by rows (rbind). When I launch it, everything is ok. When I wanna use it in shiny app there is something wrong. Below structure of tables and what shiny shows. Any suggestion? Where could be the problem? Unfortunatelly, I can not show the code, because this is for my thesis. I would be very grateful for your help.
As you can see the problem is with third column. B table has all rows with NA. After merge, all data from A table has also NA.
In shiny table is showed by renderTable.
Structure of tables A and B
I have no answer for your question, but I would like to write something and there is not enough space for this in comment section, so I will write this as answer and eventually delete later. So - I rather believe that there is something wrong with your code which you use inside shiny and would like to check this with your help. I assume you need some help with debugging, so I will post a code below:
library(shiny)
ui <- fluidPage(
tableOutput("table")
)
server <- function(input, output, session) {
my_df <- reactive({
data.frame(a = c(1, 2, 3),
b = c(4, 5, 6))
})
output$table <- renderTable({
my_df()
browser()
})
}
shinyApp(ui, server)
In the code above I have made one output (table output) and - on the server side in reactive - I'm creating data.frame. Then I use this reactive function inside my output (output$plot). However, the last line inside output$plot is function browser() which is used for debugging. You can try my code in your console and see that when you run shiny app, it immediately moving back to console (but this is "dubugging state", so console looks a little different, for example there is a button "stop" with red square which can be use to close debugging state). Please run my shiny app and when you will be back in the console, in the debugging state, type my_df() to see the data.frame object. Could you please do the same with your shiny app? I mean, could you use browser() function on the last line in your renderTable? And come back and tell if the last column contains only NA or not when displayed in the console? If not, then I would say that you are doing something different in Shiny than manually with your tables.

R Shiny run task/script in different process

In my Shiny app users can generate heavy powerpoint report. When it contains a lot of slides it could take > 30 minutes to be done. And therefore I'd like to process those tasks in independent processes/tasks which could work even when app is closed - e.g. user clicks button to generate report, closes app and when report is ready app informs user by email.
Are there any good practices or proven solutions to do this?
My first thought was using future package with plan(multisession) set - but I'm not sure what happens when user closes the app - future session closes too or not?
I was lucky enough to be at London EARL this week and I think one of the best presentations I saw there was about exactly this (by Joe Cheng). You would need the promises package for this to work and as it says on the documentation a special version of shiny devtools::install_github("rstudio/shiny#async") that supports asynchronous programming.
You can find a first documentation here on how this works by using dplyr and promises (future is also compatible).
As a small example (taken from the documentation), running an intensive calculation using the following:
read.csv.async("data.csv") %...>%
filter(state == "NY") %...>%
arrange(median_income) %...>%
head(10) %...>%
View()
would essentially return the console cursor back, allowing you to run any other command you want and would automatically open the View tab once this was finished. I might be able to dig out a shiny example in a bit, but keep in mind this is still under development and will be released before the end of the year (with a more comprehensive documentation I would imagine).
So I made some example workaround using future package. Code executes in separate session (cluster) even when app is closed. I think the next step is just to figure out how app should check if process is still running or is finished. Any ideas?
library(future)
cl <- parallel::makeCluster(2L)
plan(cluster, workers = cl)
server <- function(input, output) {
observeEvent(input$run, {
iteration <- as.numeric(input$iteration)
path <- input$path
future::future({
writeLog <- function(n, path) {
file.remove(path)
for (i in 1:n) {
cat("#", i, "-", as.character(Sys.time()), "\n", file = path, append = TRUE)
Sys.sleep(1)
}
}
writeLog(iteration, path)
}, globals = c("iteration", "path"))
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
tags$div("This app writes to file in cluster which means it is computed in parallel to this session.
It will execute even when app is closed.")
, br()
, shiny::textInput("path", "Path to log file", value = "/src/dev/export_performance/future.log")
, shiny::textInput("iteration", "Iteration number", value = 60)
),
mainPanel(
br()
, actionButton("run", "Run future")
)
)
)
shinyApp(ui = ui, server = server)

How can a shiny app recognize when a complete word has been typed into a text input?

In Shiny, text input can be provided by the user. When a user is typing, I want to executed server side code, but only once a complete word has been typed. Can I execute whenever "space" is entered?
I don't know any packages that would actually check for the entire word. As you can imagine other languages probably will need to be included in there too. Given an example with an activation if a string has a space you can do the following: Note that the space doesn't have to be after something is typed and will activate if there are any spaces in the string. To include more test cases I suggest you play around with regexpr, library(stringr), library(stringi). Have a look R Programming/Text Processing for some examples
rm(list = ls())
library(shiny)
ui =(pageWithSidebar(
headerPanel("Words With Spaces"),
sidebarPanel(
textInput("my_text", "Type something (will activate if has space):", "")),
mainPanel(textOutput("text"))
))
server = function(input, output, session){
output$text <- renderText({
if(is.na(is.null(input$my_text)) || is.null(input$my_text)){return()}
if(regexpr(" ",input$my_text)[1] > 0){input$my_text}
})
}
runApp(list(ui = ui, server = server))

Resources