RShiny integration with google sites - html

I would like to be able to add interactive shiny elements into a website. My HTML skills are not up to speed to make fancy websites from scratch. Google allows you to make nice slick well functioning websites fast, using sites.google.com.
I was wondering if it is possible to add R Shiny elements into a sites.google.com site.
For example, it is possible to put
library(plotly)
trace_0 <- rnorm(100, mean = 5)
trace_1 <- rnorm(100, mean = 0)
trace_2 <- rnorm(100, mean = -5)
x <- c(1:100)
data <- data.frame(x, trace_0, trace_1, trace_2)
p <- plot_ly(data, x = ~x, y = ~trace_0, name = 'trace 0', type = 'scatter', mode = 'lines') %>%
add_trace(y = ~trace_1, name = 'trace 1', mode = 'lines+markers') %>%
add_trace(y = ~trace_2, name = 'trace 2', mode = 'markers')
into https://sites.google.com/view/shinytest ?
EDIT: I read that in Shiny you can build a 'raw' HTML UI instead of a ShinyUI (shiny.rstudio.com/articles/html-ui.html). Would it be possible to extract the HTML from an existing site (e.g. the sites.google site from the example and keep all its functionality) and start using that as a base HTML UI in which Shiny elements can be added (and thususing the server part as back-end)?

Related

R - combine image and table then export as PDF

I have four goals:
Connect to a Postgresql database and pull some data
Gloss up a table with some colour and formatting
Include an image (company logo) above it
Export as PDF
1 and 2 are easy enough and 4 seems possible even if not convenient, but I don't think R was designed to add and position images. I've attached some sample code of how I envision creating the table, and then a mockup of what I think the final version might look like. Can anyone advise on the best way to accomplish this?
Sample data:
data(mtcars)
df <- head(mtcars)
HTML approach: flexible and portable to other apps
library(tableHTML)
html_table <- df %>%
tableHTML(rownames = FALSE, border = 0) %>%
add_css_row(css = list(c('font-family', 'text-align'), c('sans-serif', 'center'))) %>%
add_css_header(css = list(c('background-color', 'color'), c('#173ACC', 'white')), headers = 1:ncol(df))
Grob approach: Creating a ggplot-like image. I've seen recommendations to use grid.arrange to place an image on top and export as a PDF
library(ggpubr)
tbody.style = tbody_style(color = "black",
fill = "white", hjust=1, x=0.9)
grob_table <- ggtexttable(df, rows = NULL,
theme = ttheme(
colnames.style = colnames_style(color = "white", fill = "#173ACC"),
tbody.style = tbody.style
)
)
grid.arrange(table_image)
You are almost there. You just need to import your image (could be png, jpeg or svg) then pass it to grid::rasterGrob. Use the options in rasterGrob to adjust size etc. Then pass your grob table to gridExtra::grid.arrange
logo_imported <- png::readPNG(system.file("img", "Rlogo.png", package="png"), TRUE)
lg <- grid::rasterGrob(logo_imported)
gridExtra::grid.arrange(lg, grob_table)
You can then either render this to pdf by adding it to an rmarkdown report (probably best), or you can save directly to pdf via
gridExtra::grid.arrange(lg, grob_table)
pdf(file = "My Plot.pdf",
width = 4, # The width of the plot in inches
height = 4)

embed shiny app into Rmarkdown html document

I am able to create an Rmarkdown file and I'm trying to embed a shiny app into the html output. The interactive graph shows if I run the code in the Rmarkdown file. But in the html output it only shows a blank box. Can anybody help fix it?
Run the code in Rmarkdown file:
In the html output:
My Rmarkdown file (please add the three code sign at the end yourself somehow i cannot do here):
---
title: "Data Science - Tagging"
pagetitle: "Data Science - Style Tagging"
author:
name: "yyy"
params:
creation_date: "`r format(Sys.time(), c('%Y%m%d', '%h:%m'))`"
runtime: shiny
---
```{r plt.suppVSauto.week.EB, out.width = '100%'}
data <- data.frame(BclgID = c('US','US','US','UK','UK','UK','DE','DE','DE'),
week = as.Date(c('2020-06-28', '2020-06-21', '2020-06-14', '2020-06-28', '2020-06-21', '2020-06-14', '2020-06-28', '2020-06-21', '2020-06-14')),
value = c(1,2,3,1,2,2,3,1,1))
shinyApp(
ui <- fluidPage(
radioButtons(inputId = 'BclgID', label = 'Catalog',
choices = type.convert(unique(plot$BclgID), as.is = TRUE),
selected = 'US'),
plotOutput("myplot")
),
server <- function(input, output) {
mychoice <- reactive({
subset(data, BclgID %in% input$BclgID)
})
output$myplot <- renderPlot({
if (length(row.names(mychoice())) == 0) {
print("Values are not available")
}
p <- ggplot(mychoice(), aes(x=as.factor(week), y=value)) +
geom_line() +
labs(title = "test",
subtitle = "",
y="Value",
x ="Date") +
theme(axis.text.x = element_text(angle = 90)) +
facet_wrap( ~ BclgID, ncol = 1)
print(p)
}, height = 450, width = 450)
}
)
EDIT:
Coming back another year later in case anyone still finds this useful. Having done some more work with both shiny and rmarkdown so I understand both better, there isn't really a reason to use them together. Rmarkdown's advantage is being able to come up with a somewhat static pdf that is readable, where shiny is dynamic and requires input.
While my answer below works, if you're using shiny for a GUI, consider removing the rmarkdown portion of what you are writing. It probably isn't adding much/anything, and trying to use the two together can cause headaches.
Original answer below:
I see this was asked a long time ago, so you've probably moved on, but I ran into the same problem and this came up first, so I'll answer it in case anyone else runs into this problem.
I found the answer on this page:
https://community.rstudio.com/t/embedding-shiny-with-inline-not-rendering-with-html-output/41175
The short of it is shiny documents need to be run and not rendered. Rather than calling:
>rmarkdown::render("filename.rmd")
we need to call:
>rmarkdown::run("filename.rmd")
If you are inside Rstudio, it seems the "knit" function changes from render to run when using shiny in RMD.

Extend width of column with renderDataTable in Shiny

I having trouble understanding the behavior of renderDataTable function using Shiny.
I am trying to extend the width of one specific column.
When I am not using Shiny, and just trying to visualize the output of the table, I write the below and I get the expected output in the plot (Amazon Title column is extended):
Category <- c("Tools & Home Improvement", "Tools & Home Improvement")
AmazonTitle <- c("0.15,Klein Tools NCVT-2 Non Contact Voltage Tester- Dual Range Pen Voltage Detector for Standard and Low Voltage with 3 m Drop Protection", " ABCDFGEGEEFE")
ASIN_url <- c("<a href='https://www.amazon.com/dp/B004FXJOQO'>https://www.amazon.com/dp/B004FXJOQO</a>", "<a href='https://www.amazon.com/dp/B004FXJOQO'>https://www.amazon.com/dp/B0043XJOQO</a>")
ASIN <- c("B004FXJOQO", "B0043XJOQO")
All_ASIN_Information <- data.frame(Category, AmazonTitle, ASIN_url, ASIN)
DT::datatable(All_ASIN_Information, escape=FALSE,
options = list(
pageLength = 20, autoWidth = TRUE,
columnDefs = list(list( targets = 2, width = '600px'))
)
)
But when I use this exact block inside a DT::renderDataTable function for Shiny, the result is different and the column width is not extended....
See behavior for Shiny with below code:
library(shiny)
library(DT)
ui <- fluidPage(
mainPanel(
DT::dataTableOutput("Table_ASIN")))
server <- function(input, output){
output$Table_ASIN <- DT::renderDataTable(
DT::datatable(All_ASIN_Information, escape=FALSE,
options = list(
pageLength = 20, autoWidth = TRUE,
columnDefs = list(list( targets = 2, width = '600px'))
)))
}
shinyApp(ui, server)
I don't know if this behavior is caused by the hyperlinks created in column 'ASIN_url' but I would really need them anyway.
Any help much appreciated on this !
One option would be to shorten the link like this:
ASIN_url <- c("<a href='https://www.amazon.com/dp/B004FXJOQO'>Link</a>", "<a href='https://www.amazon.com/dp/B004FXJOQO'>Link</a>")
Another would be to add a scroll bar by including scrollX = TRUE in the option list

Edit map with "R for leaflet"

I have a script which allows me to generate a map with with "R for leaflet" :
library(htmlwidgets)
library(raster)
library(leaflet)
# PATHS TO INPUT / OUTPUT FILES
projectPath = "path"
#imgPath = paste(projectPath,"data/cea.tif", sep = "")
#imgPath = paste(projectPath,"data/o41078a1.tif", sep = "") # bigger than standard max size (15431804 bytes is greater than maximum 4194304 bytes)
imgPath = paste(projectPath,"/test.tif", sep = "")
outPath = paste(projectPath, "/leaflethtmlgen.html", sep="")
# load raster image file
r <- raster(imgPath)
# reproject the image, if necessary
#crs(r) <- sp::CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
# color palette, which is interpolated ?
pal <- colorNumeric(c("#FF0000", "#666666", "#FFFFFF"), values(r),
na.color = "transparent")
# create the leaflet widget
m <- leaflet() %>%
addTiles() %>%
addRasterImage(r, colors=pal, opacity = 0.9, maxBytes = 123123123) %>%
addLegend(pal = pal, values = values(r), title = "Test")
# save the generated widget to html
# contains the leaflet widget AND the image.
saveWidget(m, file = outPath, selfcontained = FALSE, libdir = 'leafletwidget_libs')
My problem is that this is generating a html file and I need this map to be dyanamic. For example, when a user click on some html button which is not integrate on the map, I want to add a rectangle on the map. Any solutions would be welcome...
Leaflet itself does not provide the interactive functionality you are looking for. One solution is to use shiny, which is a web application framework for R. From simple R code, it generates a web page, and runs R on the server-side to respond to user interaction. It is well documented, has a gallery of examples, and a tutorial to get new users started.
It works well with leaflet. One of the examples on the shiny web site uses it, and also includes a link to the source code.
Update
Actually, if simple showing/hiding of elements is enough, leaflet alone will suffice with the use of groups. From the question it's not very clear how dynamic you need it to be.

Generate an HTML report based on user interactions in shiny

I have a shiny application that allows my user to explore a dataset. The idea is that the user explores the dataset, and any interesting things the user finds he will share with his client via email. I don't know in advance how many things the user will find interesting. So, next to each table or chart I have an "add this item to the report" button, which isolates the current view and adds it to a reactiveValues list.
Now, what I want to do is the following:
Loop through all the items in the reactiveValues list,
Generate some explanatory text describing the item (This text should preferably be formatted HTML/markdown, rather than code comments)
Display the item
Capture the output of this loop as HTML
Display this HTML in Shiny as a preview
write this HTML to a file
knitr seems to do exactly the reverse of what I want - where knitr allows me to add interactive shiny components in an otherwise static document, I want to generate HTML in shiny (maybe using knitr, I don't know) based on static values the user has created.
I've constructed a minimum not-working example below to try to indicate what I would like to do. It doesn't work, it's just for demonstration purposes.
ui = shinyUI(fluidPage(
title = "Report generator",
sidebarLayout(
sidebarPanel(textInput("numberinput","Add a number", value = 5),
actionButton("addthischart", "Add the current chart to the report")),
mainPanel(plotOutput("numberplot"),
htmlOutput("report"))
)
))
server = shinyServer(function(input, output, session){
#ensure I can plot
library(ggplot2)
#make a holder for my stored data
values = reactiveValues()
values$Report = list()
#generate the plot
myplot = reactive({
df = data.frame(x = 1:input$numberinput, y = (1:input$numberinput)^2)
p = ggplot(df, aes(x = x, y = y)) + geom_line()
return(p)
})
#display the plot
output$numberplot = renderPlot(myplot())
# when the user clicks a button, add the current plot to the report
observeEvent(input$addthischart,{
chart = isolate(myplot)
isolate(values$Report <- c(values$Report,list(chart)))
})
#make the report
myreport = eventReactive(input$addthischart,{
reporthtml = character()
if(length(values$Report)>0){
for(i in 1:length(values$Report)){
explanatorytext = tags$h3(paste(" Now please direct your attention to plot number",i,"\n"))
chart = values$Report[[i]]()
theplot = HTML(chart) # this does not work - this is the crux of my question - what should i do here?
reporthtml = c(reporthtml, explanatorytext, theplot)
# ideally, at this point, the output would be an HTML file that includes some header text, as well as a plot
# I made this example to show what I hoped would work. Clearly, it does not work. I'm asking for advice on an alternative approach.
}
}
return(reporthtml)
})
# display the report
output$report = renderUI({
myreport()
})
})
runApp(list(ui = ui, server = server))
You could capture the HTML of your page using html2canvas and then save the captured portion of the DOM as a image using this answer, this way your client can embed this in any HTML document without worrying about the origin of the page contents