Jonathan Sidi, Metrum Research Group

We are happy to bring the slick JavaScript library to R. It is self-described as “the last carousel you’ll ever need”. This carousel is based on putting the elements of the carousel in a div HTML tag. This makes the carousel very versatile in what can be placed inside. Regular objects that are placed in a carousel can be for example: images, plots, tables, gifs, videos, iframes and even htmlwidgets.

This tool helps review multiple outputs in an efficient manner and saves much needed space in documents and Shiny applications, while creating a user friendly experience.

These carousels can be used directly from the R console, from RStudio, in Shiny apps and R Markdown documents.

Installation

CRAN

install.packages('slickR')

Github (dev)

devtools::install_github('metrumresearchgroup/slickR')

Examples

Images

Some web scraping for the images example….

#NBA Team Logos
nbaTeams=c("ATL","BOS","BKN","CHA","CHI","CLE","DAL","DEN","DET","GSW",
    "HOU","IND","LAC","LAL","MEM","MIA","MIL","MIN","NOP","NYK",
    "OKC","ORL","PHI","PHX","POR","SAC","SAS","TOR","UTA","WAS")
teamImg=sprintf("https://i.cdn.turner.com/nba/nba/.element/img/4.0/global/logos/512x512/bg.white/svg/%s.svg",nbaTeams)

#Player Images
a1=read_html('http://www.espn.com/nba/depth')%>%html_nodes(css = '#my-teams-table a')
a2=a1%>%html_attr('href')
a3=a1%>%html_text()
team_table=read_html('http://www.espn.com/nba/depth')%>%html_table()
team_table=team_table[[1]][-c(1,2),]
playerTable=team_table%>%melt(,id='X1')%>%arrange(X1,variable)
playerName=a2[grepl('[0-9]',a2)]
playerId=do.call('rbind',lapply(strsplit(playerName,'[/]'),function(x) x[c(8,9)]))
playerId=playerId[playerId[,1]!='phi',]
playerTable$img=sprintf('http://a.espncdn.com/combiner/i?img=/i/headshots/nba/players/full/%s.png&w=350&h=254',playerId[,1])

Grouped Images

There are players on each team, so lets group the starting five together and have each dot correspond with a team:

slickR(
  obj = playerTable$img,
  slideId = c('ex2'),
  slickOpts = list(
    initialSlide = 0,
    slidesToShow = 5,
    slidesToScroll = 5,
    focusOnSelect = T,
    dots = T
  ),
  height = 100,width='100%'
)

Replacing the dots

Sometimes the dots won’t be informative enough so we can switch them with an HTML object, such as text or other images. We can pass to the customPaging argument javascript code using the htmlwidgets::JS function.

Replace dots with text

cP1=JS("function(slick,index) {return '<a>'+(index+1)+'</a>';}")

slickR(
  obj = playerTable$img,
  slideId = 'ex3',
  dotObj = teamImg,
  slickOpts = list(
    initialSlide = 0,
    slidesToShow = 5,
    slidesToScroll = 5,
    focusOnSelect = T,
    dots = T,
    customPaging = cP1
  ),
  height=100,width='100%'
)

Replace dots with Images

cP2=JS("function(slick,index) {return '<a><img src= ' + dotObj[index] + '  width=100% height=100%></a>';}")


#Replace dots with Images
s1 <- slickR(
  obj = playerTable$img,
  dotObj = teamImg,
  slickOpts = list(
    initialSlide = 0,
    slidesToShow = 5,
    slidesToScroll = 5,
    focusOnSelect = T,
    dots = T,
    customPaging = cP2
  ),height = 200,width='100%'
)

#Putting it all together in one slickR call
s2 <- htmltools::tags$script(
  sprintf("var dotObj = %s", jsonlite::toJSON(teamImg))
)

htmltools::browsable(htmltools::tagList(s2, s1))

Plots

To place plots directly into slickR we use svglite to convert a plot into svg code using xmlSVG and then convert it into a character object

plotsToSVG=list(
  #Standard Plot
    xmlSVG({plot(1:10)},standalone=TRUE),
  #lattice xyplot
    xmlSVG({print(xyplot(x~x,data.frame(x=1:10),type="l"))},standalone=TRUE),
  #ggplot
    xmlSVG({show(ggplot(iris,aes(x=Sepal.Length,y=Sepal.Width,colour=Species))+
                   geom_point())},standalone=TRUE), 
  #lattice dotplot
    xmlSVG({print(dotplot(variety ~ yield | site , data = barley, groups = year,
                          key = simpleKey(levels(barley$year), space = "right"),
                          xlab = "Barley Yield (bushels/acre) ",
                          aspect=0.5, layout = c(1,6), ylab=NULL))
            },standalone=TRUE) 
)

#make the plot self contained SVG to pass into slickR 
s.in=sapply(plotsToSVG,function(sv){paste0("data:image/svg+xml;utf8,",as.character(sv))})
slickR(s.in,slideId = 'ex4',slickOpts = list(dots=T), height = 200,width = '100%')

Synching Carousels

There are instances when you have many outputs at once and do not want to go through all, so you can combine two carousels one for viewing and one for searching.

slickR(rep(s.in,each=5),slideId = c('ex5up','ex5down'),
       slideIdx = list(1:20,1:20),
       synchSlides = c('ex5up','ex5down'),
       slideType = rep('img',4),
       slickOpts = list(list(slidesToShow=1,slidesToScroll=1),
                        list(dots=F,slidesToScroll=1,slidesToShow=5,
                             centerMode=T,focusOnSelect=T)
                        ),
       height=100,width = '100%'
       )