RShiny - overly reactive output - r

A simple question that's confounded me related to the reactivity within R Shiny.
My desired final output is a simple list, as below:
Selected Entities: {list that's reactive based on entities selected in checkbox input}
My problem is that I do not know how to get the "Selected Entities:" part to only show up once. I have tried several variations, including trying to use the paste function in the ui.R output section, in the renderText function in server.R, and within the reactive function in which I aggregate the chosen entities.
What I've landed at is the following (this is the last case from above):
paste("Selected entities:",input$thing[1:length(input$thing)])
The output here gives all the selections but prefaces every single one with the "Selected companies:", which looks quite ugly.
Thanks for helping an R beginner!

Collapse the input$thing first:
paste("Selected entities:", paste(input$thing, collapse = ", "))
Here's a reproducible example:
paste("Letters:", paste(letters[1:5], collapse = ", "))

Related

How to generate simple html table using Shiny and R without using renderTable function?

I'm really new to R/Shiny, I'm working on a project and I'm having a problem.
Indeed, according to what I learned on the documentation, the renderTable function makes it possible to generate a datatable from a dataframe for example but, I do not wish to use this function because, I myself would like to create the structure of my HTML table and I would like for example that it looks like an invoice where the rows, the columns are for example merged etc... except that with renderTable it is not possible to do it at least, not to my knowledge.
When I add the loop this is what happens
Finally, here is how I proceed:
The highlighted line (1578) is where I add the new lines generated above so when I comment on it the header is displayed normally.
You can do something like this to generate the body:
library(htmltools)
rows <- vector("list", length = nrow(dat))
for(i in 1:nrow(dat)){
rows[[i]] <- withTags(
tr(
td(dat[i, "column1"]),
td(dat[i, "column2"])
)
)
}
body <- do.call(tags$tbody, rows)

Replace newline with br() in Shiny output

I'm writing a Shiny app in which I display text that is loaded from a database. In the database, there might be texts like so:
This is the first line
and this is the second.
There is a list of these texts that I'm loading from the database, and I want to display them all in their own box. My backend processing of these strings looks more or less like this:
format_text <- function(text) {
shinydashboard::box(text)
}
output$text_ui <- renderUI({
map(text_list, format_text) %>%
tagList()
})
When displaying, this does not respect the newlines that are in the original strings. The entire text is displayed on one line:
This is the first lineand this is the second.
I've tried fixing this by adding the following step in my custom function:
text <- str_replace_all(text, "(\r|\n)", "<br/>")
Which results in the following text:
This is the first line<br/>and this is the second
Which is obviously not what I want either.
Now, I know that I can create new lines using the shiny::br() function. However, I'm struggling to see how I could get those to work at the right points in the string.
A minimal Shiny app to fiddle with can be found here.
Ah, the solution turns out to be deceptively simple:
format_text <- function(text) {
shinydashboard::box(
HTML(text)
)
}

R Shiny create input using renderUI and function results

I am new to R Shiny and I am trying to create an app which I need it to be as interactive as possible. One problem that I am dealing with is this. In the ui.R I have the following:
helpText("Select a feature"),
uiOutput("sliders")
And in the server.R:
output$sliders <- renderUI({
selectInput('feature_name',
'Feature name', #Description
choice = c("F1"='1', "F2"='2'))
})
My question is that is it possible to change something in renderUI so that instead of setting c("F1"='1', "F2"='2')) statically I can pass the results of a function to it so it can be more dynamic (a function which generates a feature list based on something that user does and passes the list to renderUI to create the selectInput). Something like following:
output$sliders <- renderUI({
selectInput('feature_name',
'Feature name', #Description
choice = c(feature_creator(method)))
})
Where "feature_creator" is a function and it returns: "F1"='1', "F2"='2' based on the method selected by user (variable "method" is defined and I have the value). My question to be more specific is what should "feature_creator" return as output?
Hope my question is clear enough. Let me know if I should add anything to the problem description.
Any help will be much appreciated. Thanks
Assuming that all you really need is the method argument, this is not hard.
1) Make a radioButtons() input in your ui that will let the user select a method, lets give it inputId="MethodChoice".
2) In your choice argument in the selectInput you should use choice=c(feature_creator(input$MethodChoice))
Then feature_creator will get a text value based on the method the user chooses.
In order to work in choice, feature_creator should return a named list, similar in format to what you hard-coded.

Slow grep() within shiny program

I have built a shiny application which is located at the URL below.
https://hdoran.shinyapps.io/openAnalysis/
On the tab called "Choose CrossFit Open Data" I have a textInput() function that calls a function that uses grep(), which is used to find names in a data frame.
The first time the program loads and a name is entered, the search seemingly occurs quickly and names are returned. However, when I delete the name and type a second name, the search is seemingly very slow.
Is there something I can do to optimize this so that is performs quickly always?
I'm still quite new at shiny and am not sure if somehow making this a reactive expression would help. If so, I'm not quite sure how.
Thanks in advance.
The relevant portion of code in the ui.R file
textInput("name", label = 'Enter an athlete name and find your scores',
value = "Enter Name Here")
and the relevant portion of code in the server.R file is
output$myScores <- renderPrint({
df <- filedata()
df[grep(input$name, df$Competitor),]
})
And this portion is also in the ui.R file (though I'm not sure it is relevant to the problem)
verbatimTextOutput("myScores"),
If I understand your goal correctly, you want to give the user the ability to select an input variable based on searching a the competitor column of the dataframe called by filedata()? If so, selectizeInput() is what you are looking for, using server-side selection as outlined here.
Adapted to the code you provided:
ui.r
selectizeInput("name", choices = NULL, multiple = FALSE)
server.r
updateSelectizeInput(session, "name", choices = filedata()$competitor, server = TRUE)
output$myScores <- renderPrint({
df <- filedata()
subset(df, competitor==input$name)
})

Receiving input from various actionbuttons in Shiny R

So this is somehow a follow up to my previous: Automatic GUI Generating in R Shiny wher I posted the solution to how to generate elements iteratively.
Now I am unable to recieve/check which actionbuttons have been pressed and perform some action upon press.
In general, there is a function that generates the buttons and sends it to the ui.R:
output$generateImages <- renderUI({
(...)
i <-1
for(dir in folders){
(...)
txt<-paste0("rep",i)
pp<-pathNameToImage
LL[[i]] <- list(actionButton(txt,icon=imageOutput(pp,width="100px",height="100px"),label=dir))
i<-i+1
}
return(LL)
}
in ui.R I have:
uiOutput('generateImages')
And it displays the buttons fine by accumulating them into the list called "LL".
I have tried looking for tutorials and examples but was not able to find how it is done with images, and how to later recieve input from buttons that were not created "by hand", but iteratively.
How do I access these buttons in "observe" so that I can perform a action? I have tried input$generateImages, input$LL and few others, but all of them had a value of NULL.
You'll need to access them by their unique ID. The first argument passed to actionButton is its ID. That's what you'll need to use to get it as input.
So:
LL[[i]] <- list(actionButton("SomeID"))
when you assign it, then
input[["SomeID"]]
when you want to reference it. Of course, you can use a variable instead of a hardcoded string for the ID.

Resources