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)
)
}
Related
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)
I have a Shiny app that writes a webpage and provides both an Excel file download and a PDF, through an .Rmd because I need to parameterize by country. See my previous question for the same project on how to remove empty space in the PDF: https://stackoverflow.com/questions/64210913/how-do-i-remove-empty-space-between-code-chunks-in-rmd-output-to-pdf
The PDF output is in columns: left side for tables, blank mini middle column for white space, right side for charts. I add table titles as text (I did not add them as captions because I wanted the titles formatted a certain way and couldn't figure it out that way as I don't know LaTeX). Some of the titles are long, and wrap mid-word with a hyphen. How do I make the PDF output wrap without breaking up a word?
For example, I'd like a long title to break between "with" and "extralong", without specifically telling it to break there (because my titles are dynamic, each PDF might need to wrap at a different spot(s) in the title), and then again probably between "through" and "hyphenation". Here's the R chunk where I create a long title and the colorize function:
long_title <- paste0("This really long title continues forever with extralong words that shouldn't break through hyphenation")
## https://bookdown.org/yihui/rmarkdown-cookbook/font-color.html
colorize <- function(x, color) {
if (knitr::is_latex_output()) {
sprintf("\\textcolor[HTML]{2A64AB}{%s}", x)
} else if (knitr::is_html_output()) {
sprintf("<span style = 'color: %s;'>%s</span>", color, x)
} else x
}
The call:
**r colorize(long_title, color = "#2A64AB")**
The output, NOT the way I want it:
I am trying to build Shiny App that does sentiment analysis. I have the code that works fine when i execute the script normally where Rstudio is importing the data from email.csv file. This file contains only 2 columns ( SentTo and RawText) and the text i am analyzing is located in B2 cell.
Once i run the code below i get nice chart that measure the sentiment.
library(readr)
library("ggplot2")
library('syuzhet')
Emails <- read_csv("C:/email.csv")
d<-get_nrc_sentiment(Emails$RawText)
td<-data.frame(t(d))
td_new <- data.frame(rowSums(td[1:14]))
names(td_new)[1] <- "count"
td_new <- cbind("sentiment" = rownames(td_new), td_new)
rownames(td_new) <- NULL
td_new2<-td_new[1:8,]
qplot(sentiment, data=td_new2, weight=count,
geom="bar",fill=sentiment)+ggtitle("Email sentiments")
Now what i am trying to do is to modify this code a bit and build the Shiny application by doing next:
ui.R
# Adding the Imput text field to the app
shinyUI(fluidPage(
textAreaInput("UserInput", "Caption", "Please Enter Your Text", width =
"500px", height = "300px"),
mainPanel(
plotOutput("distPlot"))
))
Server.R
library(shiny)
library(syuzhet)
library(ggplot2)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
Emails <- input$UserInput
d<-get_nrc_sentiment(Emails)
td<-data.frame(t(d))
td_new <- data.frame(rowSums(td[1:14]))
names(td_new)[1] <- "count"
td_new <- cbind("sentiment" = rownames(td_new), td_new)
rownames(td_new) <- NULL
td_new2<-td_new[1:8,]
qplot(sentiment, data=td_new2, weight=count,
geom="bar",fill=sentiment)+ggtitle("Email sentiments")
})
})
After i run the app i get this error:
So ti builds the app but even when i paste some text in to the field it seems that the code i am using in server.R part is not doing what it needs to do.
If i replace the line in server.R part (Emails <- input$UserInput) with (Emails <- read_csv("C:/email.csv"))
than it works fine. This tells me that the issue is within the way i am passing the text to the Emails. Through the input form its text through the csv file it is a second row and second column that contains the data. The code that follows i think its looking that specific format.
Anybody has suggestion on how to modify this to make it work?
Thank you in advance.
I believe the issue is in line:
td_new <- data.frame(rowSums(td[1:14]))
If I change it to the following, it works for me:
td_new <- data.frame(rowSums(td))
I'm not sure why you had the 1:14 index in there, but I don't see what it does.
Before plotting in shiny, first have it output the user input so that you understand what is being passed to the next step. verbatimTextOutput('input$UserInput') and verbatimTextOutput('dput(input$UserInput)'). I'm guessing this will be a character vector of length 1.
Now, go back to your code outside of shiny and pass it this same input, formatted exactly the same. Right now your code that works is getting a data.frame from a csv file and passed a column, which would be a character vector.
Once you get it working outside of shiny, using the input as parsed by shiny, the fixes to make your shiny app work should be clear.
I have a question about shiny. Can I partly take my input from a file.
For example I have 10 variables, 6 of them I introduce from keyboard and the rest of them, 4 I want to upload from a file. Is something like this possible with shiny?
My server.R looks something like this:
results<-simSIR(nsimulations=input$nsimulations,
ncows=input$ncows,
nvaccinated=input$nvaccinated,
ninfectedinit=input$ninfectedinit,
initvaccination=input$initvaccination,
p=input$p,
freqvacc=input$freqvacc,
noutbreaks=input$noutbreaks,
lambdaiv=input$lambdaiv,
lambdain=input$lambdain,
muiv=input$muiv,
muin=input$muin,
an=input$an,
bn=input$bn,
av=input$av,
bv=input$bv,
cost_vaccination=input$cost_vaccination,
daily_milk=input$daily_milk,
price_liter=input$price_liter,
grafic=F,
parameters=T,
writeitdown=F
)
})
And as you see I take from input all, and I wanted to take some parameters like: lambaiv,lambain,muiv,muin,an,bn,bv,av from a text file.
Thank you in advance!
It's not clear what you have tried so far or what exactly you want to accomplish but this tutorial shows how to work with data files.
The key in that tutorial seems to be:
counties <- readRDS("census-app/data/counties.rds")
The is also an example using the reactiveFileReader at this link.
fileData <- reactiveFileReader(1000, session, 'data.csv', read.csv)
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 = ", "))