r - Sorting of Barts-ggplot2 in shiny using reactive - r

Please find the code below for a shiny App using ggplot2, I do not know how to sort them inside the server.R code.
WIth the below code I am able to display the bar chart and change it but ordering the data seems to be an issue.
ui.R
ui <- fluidPage(
titlePanel("Perdas no Gefin"),
theme = shinythemes::shinytheme('yeti'),
sidebarLayout(
sidebarPanel(selectInput('mes', 'Selecione o mês', unique(month(roi$Data_Contab))),
mainPanel(
tabsetPanel(
tabPanel('Word', plotly::plotlyOutput('contagem'))
))
)
)
server.R
server <- function(input, output, session){
rcontagem <- reactive({
roi %>%
filter(month(Data_Contab) == input$mes) %>%
unnest_tokens(word, Parecer) %>%
anti_join(stop_words2) %>%
count(word) %>%
na.omit() %>%
top_n(30) %>%
arrange(desc(n))
})
output$contagem <- plotly::renderPlotly({
rcontagem()%>%
ggplot(aes(x = word, y = n)) +
geom_col() +
# Flip the plot coordinates
coord_flip() +
ggtitle("Contagem de palavras")
})
}
shinyApp(ui = ui, server = server)
Plot without order:
I already tried this: Sorting of Bars-ggplot2 in shiny, but it didn't work, probably because I'm using reactive.

You could try something like this on your server side:
server <- function(input, output, session){
rcontagem <- reactive({
roi %>%
filter(month(Data_Contab) == input$mes) %>%
unnest_tokens(word, Parecer) %>%
anti_join(stop_words2) %>%
count(word) %>%
na.omit() %>%
top_n(30) %>%
arrange(desc(n))
})
output$contagem <- plotly::renderPlotly({
rcontagem()%>%
ggplot(aes(x = reorder(word,n), y = n)) +
geom_col() +
# Flip the plot coordinates
coord_flip() +
ggtitle("Contagem de palavras")
})
}

Related

Shiny: Add a plot to a column in uiOutput

I am dynamically generating fluidrows for a uiOutput because the user selection will determine how many rows there are. For each row, I have 3 columns - two are text and the third is a plot.
I've got the text working, but I"m struggling to figure out how to get the plot in there.
In the reprex below it's the same plot, but in my actual example I will need to use a table other than the one passed into map(), but filter it based on one of the .x values.
library(tidyverse)
ui <- fluidPage(
uiOutput("row_mt")
)
server <- function(input, output) {
output$row_mt <- renderUI({
mt_list <- mtcars %>%
rownames_to_column(var = "model") %>%
rowwise() %>%
group_split() %>%
map(~{
tagList(fluidRow(
column(4,
.x$model),
column(4,
.x$mpg),
column(4,
mtcars %>%
filter(cyl == .x$cyl) %>%
ggplot(aes(x = mpg, y = cyl)) + geom_point())
),
br()
)
})
tagList(mt_list)
})
}
shinyApp(ui, server)
You should try to create the plot with renderPlot, and then display it in the renderUI with a plotOutput.
Try this
server <- function(input, output) {
output$myplot <- renderPlot({
mtcars %>%
rownames_to_column(var = "model") %>%
rowwise() %>%
group_split() %>%
map(~{
mtcars %>%
filter(cyl == .x$cyl) %>%
ggplot(aes(x = mpg, y = cyl)) + geom_point()
})
})
output$row_mt <- renderUI({
mt_list <- mtcars %>%
rownames_to_column(var = "model") %>%
rowwise() %>%
group_split() %>%
map(~{
tagList(fluidRow(
column(4,
.x$model),
column(4,
.x$mpg),
column(4,
plotOutput("myplot", height=100, width=100))
),
br()
)
})
tagList(mt_list)
})
}

Using custom HTML labels with str_wrap with shiny and plotly

I have a shiny which has tooltips which show the full text of a long string. I am able to show all this text in a manageable way using str_wrap function in the text argument field for the tooltip.
library(shiny)
library(tidyverse)
library(plotly)
library(stringi)
dat <- mtcars %>%
rownames_to_column(var = "model")
dat[["lorem"]] <- rep(stri_rand_lipsum(n_paragraphs = 1), 32)
ui <- fluidPage(
plotlyOutput("plot1")
)
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
p1 <- dat %>%
ggplot(aes(x = wt, y = mpg,
text = str_wrap(lorem, width = 80))) +
geom_point()
ggplotly(p1, tooltip = "text")
})
}
shinyApp(ui, server)
However, I would like to also include some other labels, for instance model and mpg, with some custom styling (i.e. bolding the column titles), along the lines of:
Cany anyone provide a solution of how to do this - I know how to do it w/o the str_wrap function, but can't figure out how to accomplish this w/ it.
Try this:
library(shiny)
library(tidyverse)
library(plotly)
library(stringi)
dat <- mtcars %>%
rownames_to_column(var = "model")
dat[["lorem"]] <- rep(stri_rand_lipsum(n_paragraphs = 1), 32)
ui <- fluidPage(
plotlyOutput("plot1")
)
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
p1 <- dat %>%
ggplot(aes(x = wt, y = mpg,
text = paste0("<b>Model:</b> ", model, "<br>",
"<b>MPG:</b> ", mpg, "<br>",
str_wrap(paste0("<b>Text:</b> ", lorem), width = 80)
))) +
geom_point()
ggplotly(p1, tooltip = "text")
})
}
shinyApp(ui, server)

Bar Plot does not Display in Shiny App, I have developed a code

I am new to the shiny app and trying to write simple code.
I changed the codes so many times but my bar chart doesn't work.
I have this problem in my other trying. That the UI works and also the codes in the server work part by part in R but not in the shiny app. I know some part of my server is not what I want, I just want to know what should I do to run the code which works in R but not in Shiny
#Graph 2
server<-#Graph 2
library("tidyverse")
library("leaflet")
library("leaflet.extras")
library("rnaturalearthdata")
library("sf")
library("DT")
library("ggplot2")
N <- read.csv("https://data.ontario.ca/dataset/f4112442-bdc8-45d2-be3c-12efae72fb27/resource/455fd63b-603d-4608-8216-7d8647f43350/download/conposcovidloc.csv")
function(input, output, session){
if(input$data.Gender){
City ="Ottawa"
N %>% subset(Reporting_PHU_City == City) %>%
select(Case_Reported_Date, Age_Group, Client_Gender, Outcome1)%>%
rename(Date = Case_Reported_Date)%>%
arrange(Age_Group, Client_Gender, Outcome1)
Data.N <- as.data.frame(N)
Data.N %>%
group_by(Age_Group) %>%
summarise(Age = n_distinct(Age_Group)) %>%
arrange(desc(Age))
w = table(N$Age_Group)
t = as.data.frame(w)
}
output$Plot <- renderPlot({
ggplot() +
geom_bar(stat = "identity",data = t,mapping = aes(x = N$Client_Gender , y =Freq))
})
}
Sorry, the site didn't let me share the UI too. This is Ui
UI<- #Graph 2
library("leaflet")
library("DT")
fluidPage(
sidebarLayout(
sidebarPanel(
radioButtons("data.Gender", "",
c("Data female" = "Gender.Female",
"Data male" = "Gender.Male"))
),
enter code here
mainPanel(
plotOutput("Plot")
)
))
Perhaps you should group by Client_Gender. Your present group by of Age_Group will give 1 as the value for all groups.
Try this
server <- function(input, output, session){
t <- reactive({
input$data.Gender
City ="Toronto"
aa <- N %>% subset(Reporting_PHU_City == City) %>%
select(Case_Reported_Date, Age_Group, Client_Gender, Outcome1)%>%
rename(Date = Case_Reported_Date)%>%
arrange(Age_Group, Client_Gender, Outcome1)
bb <- aa %>%
group_by(Client_Gender) %>%
summarise(Age = n_distinct(Age_Group)) %>%
arrange(desc(Age))
bb
})
output$Plot <- renderPlot({
ggplot(data=t()) +
geom_bar(stat = "identity",mapping = aes(x = Client_Gender , y = Age))
})
}

Slider with years for barplot

I am trying to get a slider within my barplot page to make the data interactive per year.
#library
library(dplyr)
library(shiny)
library(shinythemes)
library(ggplot2)
#Source
dataset <- read.csv("Wagegap.csv")
SFWage <- dataset %>%
group_by(gender,JobTitle, Year) %>%
summarise(averageBasePay = mean(BasePay, na.rm=TRUE)) %>%
select(gender, JobTitle, averageBasePay, Year)
clean <- SFWage %>% filter(gender != "")
#UI
ui <- fluidPage(
theme = shinytheme("united"),
navbarPage("San Fransisco Wages",
tabPanel("Barplot",
mainPanel(
plotOutput("barplot")
)) ,
tabPanel("Table",
mainPanel(
dataTableOutput("table")
))
)
)
#server
server <- function(input, output){
output$barplot <- renderPlot({
ggplot(clean, aes(x = JobTitle, y = averageBasePay ))+
geom_bar(stat="Identity", width = 0.3, fill="orange")+
labs(x= "Jobs", y = "Wage", title = "Wage per job")
})
output$table <- renderDataTable({
clean
})
}
#Run App
shinyApp(ui = ui, server = server)
I don't fully understand it yet how to put this input in.
I have tried sliding it into the navbarpage but I can't figure out how it works.
I also tried making year reactive but with no success.
It's not the year that has to be reactive; it's the whole data frame. Therefore, in your ui, you can do:
[...]
tabPanel("Barplot",
mainPanel(
sliderInput("year", label = "Which year should be displayed?", min = 1900, max = 2020, step = 5, value = 2000) # new
plotOutput("barplot")
)) ,
[...]
I put it there for convenience; the layout is yours. I tried do change as little as possible.
The server would then have:
server <- function(input, output){
# NEW ########################################
clean <- reactive({
SFWage <- dataset %>%
group_by(gender,JobTitle, Year) %>%
summarise(averageBasePay = mean(as.numeric(BasePay), na.rm=TRUE)) %>% # Notice the as.numeric()
select(gender, JobTitle, averageBasePay, Year)
SFWage %>% filter(gender != "" & Year == input$year)
})
# OLD ########################################
output$barplot <- renderPlot({
ggplot(clean(), aes(x = JobTitle, y = averageBasePay ))+ # Parenthesis
geom_bar(stat="Identity", width = 0.3, fill="orange")+
labs(x= "Jobs", y = "Wage", title = "Wage per job")
})
output$table <- renderDataTable({
clean() # Parenthesis
})
}
Don't forget to add the parenthesis, as I did here.
This should work, but I might have mistyped something or got it completely wrong. Since I don't have your data, I can't test it.
EDIT: Due to your comment, I added the as.numeric() term, as you can see above. However, if your data is not only not numeric but also with ,, you can do:
[...]
summarise(averageBasePay = mean(as.numeric(gsub(",", ".", BasePay)), na.rm=TRUE)) %>% # Notice the as.numeric() and the gsub()
[...]

Shiny table formatting

I am new to Shiny and have a basic shiny app using mtcars. I have multiple tabs with some input dropdowns and presenting the output as DT tables. This is all working fine, but I would now like to use some formatting like formattable. Some of the formatting I would like to include is basic percentage, decimal. Also, I would like to add some cell based highlighting. I have tried multiple formatting functions without any luck. I have added functions within the server side output, but I can not get the right combination. Below is my Shiny code:
library(shiny)
library(dplyr)
library(DT)
ui <- fluidPage(
titlePanel("mtcars"),
sidebarLayout(
sidebarPanel(
selectInput("cyl",
"cyl:",
c(unique(as.character(mtcars$cyl)))),
selectInput("gear",
"gear:",
c("All",
unique(as.character(mtcars$gear)))), width=2),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("Summary", DT::dataTableOutput("Summary")),
tabPanel("Detail", DT::dataTableOutput("Detail"))))))
server <- function(input, output) {
output$Detail <- renderDataTable(datatable({
data <- mtcars
if (input$cyl != "All") {
data <- data[data$cyl == input$cyl,]
}
if (input$gear != "All") {
data <- data[data$gear == input$gear,]
}
data
}))
output$Summary <- renderDataTable({
mtcars %>%
filter(cyl==input$cyl) %>%
group_by(gear) %>%
summarise(mpg = median(mpg),
count = n()) %>%
ungroup() %>%
arrange(desc(count))
})}
shinyApp(ui = ui, server = server)
I'm not sure what you've tried so far with formattable, but you should be able to use it with DT in your shiny app.
Here is a quick example you can try. This makes the mpg column a percentage. Also, if colors the count column a shade of green.
Other vignettes are available for other options with formattable package.
output$Summary <- renderDataTable({
my_data <- mtcars %>%
filter(cyl==input$cyl) %>%
group_by(gear) %>%
summarise(mpg = median(mpg),
count = n()) %>%
ungroup() %>%
arrange(desc(count))
# Make percent, for example
my_data$mpg <- percent(my_data$mpg)
# Return formattable datatable
return(
as.datatable(
formattable(
my_data,
list(
count = color_tile("transparent", "green")
)
)
)
)
})
To complete Ben's answer, even if you say you want to use formattable, I think there are enough options in DT to customize the tables the way you want.
Here's your example (randomly customized since you didn't specify the formatting of the cells):
library(shiny)
library(dplyr)
library(DT)
ui <- fluidPage(
titlePanel("mtcars"),
sidebarLayout(
sidebarPanel(
selectInput("cyl",
"cyl:",
c(unique(as.character(mtcars$cyl)))),
selectInput("gear",
"gear:",
c("All",
unique(as.character(mtcars$gear)))), width=2),
mainPanel(
tabsetPanel(
id = 'dataset',
tabPanel("Summary", DT::dataTableOutput("Summary")),
tabPanel("Detail", DT::dataTableOutput("Detail"))))))
server <- function(input, output) {
output$Detail <- renderDataTable(datatable({
data <- mtcars
if (input$cyl != "All") {
data <- data[data$cyl == input$cyl,]
}
if (input$gear != "All") {
data <- data[data$gear == input$gear,]
}
data
}))
output$Summary <- renderDataTable({
your_data <- mtcars %>%
filter(cyl==input$cyl) %>%
group_by(gear) %>%
summarise(mpg = median(mpg),
count = n()) %>%
ungroup() %>%
arrange(desc(count))
datatable(your_data) %>%
formatPercentage(columns = c("mpg", "gear")) %>%
formatRound(columns = c("count"), digits = 3) %>%
formatStyle(columns = "mpg",
valueColumns = "gear",
backgroundColor = styleEqual(c(3, 4, 5), c("red", "blue", "green")))
})}
shinyApp(ui = ui, server = server)
See here for more details, and here for several examples of color-styling.

Resources