When I knitting the following code in Flexdashboard in R Markdown file, the entire file is not giving output on the entire page, however when I run the code chunk individually it is showing the correct output.
I have tried adjusting Column {width } as well, but nothing is happening.
title: "By sachin"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
library(flexdashboard)
Page 1
Column {data-width=650}
Chart A
library(dplyr)
library(tidyverse)
library(ggplot2)
df <- read.csv("data.csv")
#view(df)
df1 <- subset(df, select = c("year","dem","all_pass"))
#str(df1)
df1$dem <- as.character(df1$dem)
df1$dem = factor(df1$dem, levels = c(0,1),
labels = c("Democrat","Republic"))
#view(df2)
#colnames(df2)<-c("Year","Party","All Bills Passed")
df2 <-df1 %>% group_by(year,dem) %>% summarise_at(vars(all_pass),funs(sum(. , na.rm = TRUE)))
#df2 <-df1 %>% group_by(year,dem ) %>% summarise_at(vars(all_pass),funs(sum(. , na.rm = TRUE)))
ggplot(df2, aes(x=year, fill = dem )) + geom_area(aes(y = all_pass))+labs(y = "All Bills Passed", x = "Year", title = "Number of bills passed since 1980")
Page 2
Column {data-width=500}
Chart B
library(dplyr)
library(tidyverse)
library(broom)
library(ggplot2)
library(plotly)
#install.packages("jtools")
library(jtools)
df <- read.csv("data.csv")
df <- filter(df, df$congress==110)
#view(df)
df3 <- subset(df, select = c(dem, all_pass,votepct))
#view(df3)
#df3 <- filter(df3, dem ==0 & dem ==1)
#view(df3)
df3$dem <- as.character(df3$dem)
df3$dem = factor(df3$dem, levels = c(0,1),
labels = c("Democrat","Republic"))
#view(df3)
#fit<- lm(formula = votepct~dem,df3)
ggplot(df3, aes(x=votepct,y = all_pass, fill = dem,colour = dem )) + geom_point(aes(y = all_pass),size=3)+labs(y = "All Pass", x = "votepct", title = "Passage and Vote Pct , 110th Congress")+ geom_smooth(method="lm")
#df4 <-df3 %>% group_by(dem) %>% summarise_at(vars(all_pass),funs(sum(. , na.rm = TRUE)))
#view(df4)
#abline(fit)
#effect_plot(fit, pred = "dem",interval = TRUE, plot.points = TRUE)
#(fit, pred = votepct, interval = TRUE, plot.points = TRUE)
Column {data-width=500}
Chart C
library(dplyr)
library(tidyverse)
library(broom)
library(ggplot2)
library(plotly)
#install.packages("jtools")
library(jtools)
df <- read.csv("data.csv")
df <- filter(df, df$congress==110)
#view(df)
df5 <- subset(df, select = c(dem, all_pass,dwnom1))
#view(df5)
#df3 <- filter(df3, dem ==0 & dem ==1)
#view(df3)
df5$dem <- as.character(df5$dem)
df5$dem = factor(df5$dem, levels = c(0,1),
labels = c("Democrat","Republic"))
#view(df5)
fit<- lm(formula = all_pass~dwnom1,df5)
ggplot(df5, aes(x=dwnom1,y = all_pass, fill = dem,colour = dem )) + geom_point(aes(y = all_pass),size=3)+labs(y = "All Pass", x = "DW Nominate", title = "Passage and Ideology , 110th Congress")+geom_smooth(method="lm")
Page 3
Column {data-width=650}
Chart D
library(ggplot2)
library(plotly)
library(dplyr)
library(shiny)
ui <- basicPage(
h1("Total bills passed by state delegation, 110th Congress"),
selectizeInput(inputId = "bins",
label = "Choose State",
choices = state.abb,
multiple = TRUE),
plotOutput("plot")
)
server <- function(input, output) {
df <-
tibble(all_pass = sample(1:500, 350),
st_name = rep(state.abb, 7))
output$plot <- renderPlot({
req(input$bins)
df |>
filter(st_name %in% input$bins) |>
ggplot(aes(y = all_pass,x=st_name )) +
geom_bar(stat = "sum")
})
}
shinyApp(ui = ui, server = server)
Related
I must design a graph that accumulates variables as they are added in Shiny R using plotly.
For example, if I graph the variable x with respect to the date t with a select input, I add the variable and it is located on the right side of the variable x, indicating with a separator that it is the variable y and so with as many variables are selected.
This is my code:
library(shiny)
library(plotly)
library(dplyr)
set.seed(123)
df <- data.frame(x = seq.Date(as.Date("2000/1/1"), by = "month", length.out = 100),
cat = sample(c("m1","m2","m3"),100, replace = TRUE),
a = cumsum(rnorm(100)),
b = rnorm(100),
c = rnorm(100),
d = rnorm(100))
ui <- fluidPage(
selectInput("x","Variable",names(df)[-1],NULL,TRUE),
selectInput("y", "category", unique(df$cat), NULL, TRUE),
numericInput("ls","limite superior",NULL,-100,100),
numericInput("li","limite superior",NULL,-100,100),
plotlyOutput("plot1")
)
server <- function(input, output, session) {
output$plot1 <- renderPlotly({
req(input$y, input$x)
df <- df%>%
filter(cat %in% input$y)%>%
select(one_of("x",input$x))
estado <- ifelse(df[[2]]>input$ls,"red",
ifelse(df[[2]]<input$ls & df[[2]]>input$li,
"orange","green"))
df$estado <- estado
p <- plot_ly(df,
x = ~x,
y = ~df[[2]],
type = "scatter",
mode = "lines")
## Makers
p <- p %>%
add_trace(x = ~x,
y= df[[2]],
marker = list(color = ~estado, size = 20, symbol = "square"),
showlegend = FALSE)
## Lengends and labels
p <- p %>%
layout(legend = list(orientation = 'h'))%>%
layout(title = paste('Comportamiento de calidad de agua residual', input$estacion, sep=' '),
plot_bgcolor = "#e5ecf6",
xaxis = list(title = 'Fecha'),
yaxis = list(title = paste(input$x,"mg/l", sep=" ")))
print(p)
})
}
shinyApp(ui, server)
I need that when adding the variables a, b, c, d, the graph will be made just after the variable that was already there so that it looks something like this:
Use subplot and do function.
df %>%
group_by(category) %>%
do(p = plot_ly(...) %>% (plot_features...)) %>%
subplot(sharex= FALSE,sharey=TRUE, nrow=1, margin = 0.0001)
With plot feautures i mean all the deatils of the plot (markers, lines, colors, etc)
at the moment I try to create an interactive heatmap in R with apexcharter. This works fine at manual chart creation but fails on interactive use within shiny.
library(shiny)
library(tidyverse)
library(apexcharter)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Test Heatmap"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "heatmap_filter",
label = "heatmap filter",
choices = c(1999, 2008),
selected = 2008
)
),
mainPanel(
apexchartOutput("heatmap")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$heatmap <- renderApexchart({
df <- mpg %>% filter(year == input$heatmap_filter) %>% mutate_if(is.character, as.factor) %>% group_by(manufacturer, class) %>% summarise(cnt = n()) %>% tidyr::complete(class, fill = list(cnt = 0))
q20 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[2],0)
q40 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[3],0)
q60 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[4],0)
q80 <- round(as.numeric(quantile(df %>% filter(cnt>0) %>% pull(cnt), probs = seq(0,1,0.2), na.rm = TRUE))[5],0)
apex(
data = df,
type = "heatmap",
mapping = aes(x = manufacturer, y = class, fill = cnt)
) %>%
ax_dataLabels(enabled = TRUE) %>%
ax_plotOptions(
heatmap = heatmap_opts(
enableShades = FALSE,
colorScale = list(
ranges = list(
list(from = 0, to = q20, color = "#106e45"), #grün
list(from = q20, to = q40, color = "#90dbba"), #leichtes grün
list(from = q40, to = q60, color = "#fff33b"), #gelb
list(from = q60, to = q80, color = "#f3903f"), # orange
list(from = q80, to = 20, color = "#e93e3a") #rot
)
)
)
) %>%
ax_title(
text = paste("Test interactive heatmap",
input$heatmap_filter
), align = "center"
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
With the manual approach everthing works as expected. But when I change the input select only the values changes but not the heatmap quantil ranges and not the title input. Its seems like the input value is not pushing the changes to already calculated variables. I already tried to use an reactive df or reactive variables but so far nothing works.
I added a minimal example where you could change the year input and this should change the title and the color ranges.
Can you help me?
Thanks in advance.
Try setting auto_update to FALSE in the call to apex
apex(
data = df,
type = "heatmap",
auto_update = FALSE,
...
Problem:
I was trying to build a shiny app that plot frequency of n-grams based on a user specified column from a user uploaded csv. In addition, a function was added to plot the senetiment over time, based on a date column specified by the user as well.
The app was working okay locally, with Warning, but failed work after published. Please see the following for a reproducible example.
Preparation: libraries and example data
# Load R packages
library(shiny)
library(tidyverse)
library(shinythemes)
library(lubridate)
library(tidytext)
library(textdata)
# Creating a example csv file for upload
Sample_csv <-
data.frame(text = janeaustenr::emma,
id = 1:length(janeaustenr::emma),
date = sample(seq(as.Date('1900/01/01'), as.Date('1920/01/01'), by="day"),
replace = T,
length(janeaustenr::emma)))
write.csv(Sample_csv, "Sample_csv.csv", row.names = F)
UI
ui <- fluidPage(theme = shinytheme("united"),
titlePanel("Text glancer"),
sidebarLayout(
sidebarPanel(
# Input: Select a file ----
fileInput("csv_file", "Feed csv here",
multiple = FALSE,
accept = c(".csv")),
#Conditional panel
conditionalPanel(
# use a server side condition
condition = "output$fileUploaded",
# Input: Select ----
uiOutput("text_select"),
# Input: Select ----
uiOutput("date_select"),
# Input: Simple integer interval ----
sliderInput("top_frequency", "Top n ngrams to be plotted:",
min = 5, max = 20, value = 10),
# Input: Select ----
selectInput("ngrams", "Ngrams of your choice:",
c("Single word" = 1,
"Bigram" = 2,
"Trigram" = 3)
)
),
# Submit bottom
submitButton("Update View", icon("refresh"))
),
# sidebarPanel
mainPanel(
tabsetPanel(
tabPanel(h2("Most frequenlty used n-grams"),
plotOutput("frequency_plot", height = 900, width = 1200)),
tabPanel(h2("Sentiment of the months"),
plotOutput("sentiment_plot", height = 900, width = 1200))
)
)
)
)
server
server <- function(input, output, session) {
# create reactive version of the dataset (a data.frame object)
LOAD_DATA <- reactive({
infile <- input$csv_file
if (is.null(infile))
{return(NULL)}
{read_csv(infile$datapath)}
})
# inform conditionalPanel wheter dropdowns sohould be hidden
output$fileUploaded <- reactive({
return(!is.null(LOAD_DATA()))
})
outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
## update 'column' selectors
output$text_select <- renderUI({
if(is.null(LOAD_DATA()))
{return(NULL)}
else
selectInput("text_col", "Select the text column:", colnames(LOAD_DATA()))
})
output$date_select <- renderUI({
if(is.null(LOAD_DATA()))
{return(NULL)}
else
selectInput("date_col", "Select the date column (ymd):", colnames(LOAD_DATA()))
})
# Create reactive parameters
TOP_FREQUENCY <- reactive({
input$top_frequency
})
N_GRAMS <- reactive({
as.numeric(as.character(input$ngrams))
})
# Output frequency of ngrams
output$frequency_plot <- renderPlot( {
if(is.null(LOAD_DATA()))
{return(NULL)}
else{
WORK_DATA <- LOAD_DATA()[,c(input$text_col,
input$date_col)]
names(WORK_DATA) <- c("TEXTS", "DATES")
CSV_DOC_N_Grams <-
WORK_DATA %>%
# LOAD_DATA() %>%
# select(TEXTS = TEXT_COL(), DATES = DATE_COL()) %>%
mutate(TEXTS = gsub("http.*", " ", TEXTS)) %>%
# mutate(text = gsub("\\#.* |\\#.* .|\\#.* ,", " ", text)) %>%
unnest_tokens(words, TEXTS, token = "ngrams", n = N_GRAMS()) %>%
select(words) %>%
filter(str_detect(words, "[a-zA-Z]")) %>%
separate(words, c("word1","word2","word3"),sep = " ", remove = F) %>%
filter(! word1 %in% stop_words$word &
! word2 %in% stop_words$word&
! word3 %in% stop_words$word)
#Counting ngrams
CSV_DOC_N_Gramss_Count <-
CSV_DOC_N_Grams %>%
count(words, sort=T) %>%
select(N_Gram_Text = words,
N_Gram_Count = n)
#Plotting ngram frequency
CSV_DOC_N_Gramss_Count_freq <-
CSV_DOC_N_Gramss_Count %>%
mutate(N_Gram_Text = fct_reorder(N_Gram_Text, N_Gram_Count)) %>%
top_n(TOP_FREQUENCY(), N_Gram_Count) %>%
ggplot(aes(x = N_Gram_Text,
y = N_Gram_Count,
fill = N_Gram_Count)) +
geom_col()+
coord_flip() +
scale_fill_gradient2()+
labs(title = paste0("Top ", TOP_FREQUENCY(), " ngrams used in csv doc"),
x = "ngrams",
y = "frequency") +
theme_bw()+
theme(legend.position = "none",
axis.text.x = element_text(face='bold',size=12),
axis.text.y = element_text(face='bold',size=12),
axis.title.x = element_text(face='bold',size=18),
axis.title.y = element_blank())
print(CSV_DOC_N_Gramss_Count_freq)
}
})
output$sentiment_plot <- renderPlot( {
if(is.null(LOAD_DATA())){return(NULL)}
else{
WORK_DATA <- LOAD_DATA()[,c(input$text_col,
input$date_col)]
names(WORK_DATA) <- c("TEXTS", "DATES")
tk_afinn <-
WORK_DATA %>%
mutate(TEXTS = gsub("http.*", " ", TEXTS)) %>%
unnest_tokens(word, TEXTS) %>%
filter(! word %in% stop_words$word) %>%
filter(str_detect(word, "[a-zA-Z]")) %>%
filter(! DATES %in% NA) %>%
inner_join(get_sentiments("afinn")) %>%
mutate(YEAR_Month = ymd(paste(year(DATES),
month(DATES),
"1", sep="-"))) %>%
group_by(index = YEAR_Month) %>%
summarise(sentiment = sum(value))
tk_afinn_plot <-
tk_afinn %>%
ggplot(aes(x = index, y = sentiment)) +
geom_line()+
labs(x = "date (year-month)",
y = "sentiment of the month") +
theme_bw()+
theme(legend.position = "none",
axis.text.x = element_text(face='bold',size=12),
axis.text.y = element_text(face='bold',size=12),
axis.title.x = element_text(face='bold',size=18),
axis.title.y = element_blank())
print(tk_afinn_plot)
}
})
}
Fuse
shinyApp(ui = ui, server = server)
Warnings:
After loading the csv file, the local app reports :
"Problem with mutate() input TEXTS.
object 'TEXTS' not found
Input TEXTS is gsub("http.*", " ", TEXTS)."
After specify the text column and date column, both tab showed plots. However, after publishing it to shinyapp.io, it reports error and would not run.
Can anybody help with this issue? I have consulted the other thread includin this>https://stackoverflow.com/questions/47248534/dynamically-list-choices-for-selectinput-from-a-user-selected-column, but still no luck.
Any insight would be greatly appreciated!
I'm hoping to implement this ggplotly bug fix offered here:
https://community.plot.ly/t/bug-with-ggplot2-stat-ecdf-function/1187/4
into a Shiny reactive expression. The top plot below shows the ggplot() call results within Shiny (as expected), the bottom is from ggplotly().
When I try to insert data <- data[order(data$val), ] inside the reactive expression, I'm unable to subset as suggested by the fix: Error in data$val : object of type 'closure' is not subsettable and I can't seem to find any other place for it to work.
reproducible app.r:
library(tidyverse)
library(shiny)
library(shinydashboard)
library(plotly)
# generate sample p & t observation data
zone <- c(rep("a", 6), rep("b", 6), rep("c", 6), rep("d", 6))
set.seed(1)
val <- rnorm(24, 12, 18)
param <- rep(c("p", "t"), 12)
p_t <- data.frame(zone, val, param, stringsAsFactors = FALSE)
# sample elevation frequency data - too many obs to uncount all at once
set.seed(2)
val <- sample(50, 24)
count <- sample(200000, 24)
e_countcsv <- data.frame(zone, val, count, stringsAsFactors = FALSE) %>%
mutate(param = "elev")
shinyApp(
ui = fluidPage(
sidebarLayout(sidebarPanel(
selectizeInput(
"zone", "zone", choices = unique(p_t$zone),
selected = c("a"),
multiple = TRUE),
checkboxGroupInput("param", "parameter",
choices = c("elev", "p", "t"), selected =c("elev", "p"))
),
mainPanel(
tabsetPanel(position=c("right"),
tabPanel(strong("static cdf"),
br(),
plotOutput("reg_plot", height = "750px")) ,
tabPanel(strong("interactive cdf"),
br(),
plotlyOutput("plotlyPlot", height = "750px")) )))
),
server = function(input, output) {
data <- reactive({
p_t %>%
filter(param %in% input$param,
zone %in% input$zone) %>%
bind_rows({e_countcsv %>%
filter(param %in% input$param,
zone %in% input$zone) %>%
uncount(count)})
})
output$reg_plot <- renderPlot({
ggplot(data(), aes(val, color = param, linetype = zone)) +
labs(y = "proportion of total", x = NULL) +
stat_ecdf(pad = FALSE) + coord_flip()
})
output$plotlyPlot <- renderPlotly({
p <- ggplot(data(), aes(val, color = param, linetype = zone)) +
labs(y = "proportion of total", x = NULL) +
stat_ecdf(pad = FALSE) + coord_flip()
p <- ggplotly(p)
p
})
}
)
Any ideas? Thank you!
Like #MrGumble suggested you should not use data as a name because it points to a function (try to print data in your console and you will see the function).
Just give your dataset in the reactive expression another name and it will work:
data <- reactive({
dataset <- p_t %>%
filter(param %in% input$param,
zone %in% input$zone) %>%
bind_rows({e_countcsv %>%
filter(param %in% input$param,
zone %in% input$zone) %>%
uncount(count)})
dataset[order(dataset$val), ]
})
I'm trying to build a bilingual dashboard. In this dashboard I want to choose the right language column (either ENG or NL) based on input$language. This column serves as the levels input for a function in which a plotly graph is made.
The problem is now that when I use the radiobutton and change the language, nothing changes in the plotly graph. I'm guessing the regular function is not updating when something changes in the 'custom_levels_lang' reactive variable.
How can I make this work?
server.R
library(shinydashboard)
library(dplyr)
library(tidyr)
library(shiny)
library(plotly)
#make bilangual df
ID = c("level_1_graph1","level_1_graph1")
NL = c("Ja","Nee")
ENG = c("Yes","No")
levels_lang = data.frame(ID,NL,ENG)
#create df for pie-chart
S <- c("Ja","Nee")
n <- c(645,544)
percentage <- c(54,46)
df <- data.frame(S,n,percentage)
function(input, output, session) {
# Creating levels by language
custom_levels_lang <- reactive({
#select chosen language for input$language, then transpose all levels per
#graph number to separate columns
#gives custom_levels_lang$'name'
df <- levels_lang %>%
select(ID,one_of(input$language)) %>%
mutate(row = row_number()) %>%
spread_("ID",input$language)
#make list
df <- as.list(df)
#remove na's from list
df <- lapply(df, function(x) x[!is.na(x)])
return(df)
})
#create pie-chart
plot_pie <- function(custom_levels){
plt <- renderPlotly({
#give right levels based on chosen language
levels(df$S) <- custom_levels
#construct plot
df %>%
plot_ly(
labels = df$S,
values = ~percentage,
type = 'pie',
hole = 0.5,
textinfo = 'percent',
text = ~paste("n = ", n),
hoverinfo = 'text') %>%
layout(
showlegend = TRUE,
legend = list(x = 0.2, y = -0.3),
title = "title") %>%
config(
displaylogo = FALSE,
collaborate = FALSE,
modeBarButtonsToRemove = list('zoom2d','pan2d','zoomIn2d','zoomOut2d',
'autoScale2d','resetScale2d','toggleHover',
'toggleSpikelines','hoverClosestCartesian','hoverCompareCartesian'))
})
return(plt)
}
output$plt1 <- plot_pie(custom_levels = custom_levels_lang()$level_1_graph1)
}
ui.R
library(shinydashboard)
library(dplyr)
library(tidyr)
library(shiny)
library(plotly)
header <- dashboardHeader(
title = "Welcome",
titleWidth = 450)
sidebar <- dashboardSidebar(width = 300, radioButtons("language", label = "Kies taal", choices = list("Nederlands" = "NL", "English" ="ENG"), selected = "NL"))
body <- dashboardBody( plotlyOutput('plt1') )
dashboardPage(header,sidebar,body)
The renderPlotly function has to be outside the function call so that it gets notified whenever its dependency (custom_levels_lang()$level_1_graph1) changes.
In your code it's not in a reactive context, so it only gets rendered once.
plot_pie <- function(custom_levels){
#give right levels based on chosen language
levels(df$S) <- custom_levels
#construct plot
plt <- df %>%
plot_ly(
labels = df$S,
values = ~percentage,
type = 'pie',
hole = 0.5,
textinfo = 'percent',
text = ~paste("n = ", n),
hoverinfo = 'text') %>%
layout(
showlegend = TRUE,
legend = list(x = 0.2, y = -0.3),
title = "title") %>%
config(
displaylogo = FALSE,
collaborate = FALSE,
modeBarButtonsToRemove = list('zoom2d','pan2d','zoomIn2d','zoomOut2d',
'autoScale2d','resetScale2d','toggleHover',
'toggleSpikelines','hoverClosestCartesian','hoverCompareCartesian'))
return(plt)
}
output$plt1 <- renderPlotly(plot_pie(custom_levels = custom_levels_lang()$level_1_graph1))