├── .gitignore ├── README.md ├── cranview.Rproj ├── server.R └── ui.R /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | View CRAN Package Downloads with Shiny 2 | ------------------ 3 | 4 | A Shiny app to visualize downloads from RStudio's CRAN mirror. 5 | 6 | View the app [here](https://dgrtwo.shinyapps.io/cranview/), or read more about it [here](http://varianceexplained.org/r/cran-view). 7 | -------------------------------------------------------------------------------- /cranview.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 4 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /server.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(stringr) 3 | library(dplyr) 4 | library(ggplot2) 5 | library(lubridate) 6 | library(cranlogs) 7 | library(zoo) 8 | library(scales) 9 | 10 | get_initial_release_date = function(packages) 11 | { 12 | min_date = Sys.Date() - 1 13 | 14 | for (pkg in packages) 15 | { 16 | # api data for package. we want the initial release - the first element of the "timeline" 17 | pkg_data = httr::GET(paste0("http://crandb.r-pkg.org/", pkg, "/all")) 18 | pkg_data = httr::content(pkg_data) 19 | 20 | initial_release = pkg_data$timeline[[1]] 21 | min_date = min(min_date, as.Date(initial_release)) 22 | } 23 | 24 | min_date 25 | } 26 | 27 | shinyServer(function(input, output) { 28 | downloads <- reactive({ 29 | packages <- input$package 30 | cran_downloads0 <- failwith(NULL, cran_downloads, quiet = TRUE) 31 | cran_downloads0(package = packages, 32 | from = get_initial_release_date(packages), 33 | to = Sys.Date()-1) 34 | }) 35 | 36 | output$downloadsPlot <- renderPlot({ 37 | d <- downloads() 38 | if (input$transformation=="weekly") { 39 | d$count=rollapply(d$count, 7, sum, fill=NA) 40 | } else if (input$transformation=="cumulative") { 41 | d = d %>% 42 | group_by(package) %>% 43 | transmute(count=cumsum(count), date=date) 44 | } 45 | 46 | ggplot(d, aes(date, count, color = package)) + geom_line() + 47 | xlab("Date") + 48 | scale_y_continuous(name="Number of downloads", labels = comma) 49 | }) 50 | 51 | }) 52 | -------------------------------------------------------------------------------- /ui.R: -------------------------------------------------------------------------------- 1 | library(shiny) 2 | library(httr) 3 | library(jsonlite) 4 | 5 | # get the list of all packages on CRAN 6 | package_names = names(httr::content(httr::GET("http://crandb.r-pkg.org/-/desc"))) 7 | 8 | shinyUI(fluidPage( 9 | 10 | # Application title 11 | titlePanel("Package Downloads Over Time"), 12 | 13 | # Sidebar with a slider input for number of bins 14 | sidebarLayout( 15 | sidebarPanel( 16 | HTML("Enter an R package to see the # of downloads over time from the RStudio CRAN Mirror.", 17 | "You can enter multiple packages to compare them"), 18 | selectInput("package", 19 | label = "Packages:", 20 | selected = sample(package_names, 2), # initialize the graph with a random package 21 | choices = package_names, 22 | multiple = TRUE), 23 | radioButtons("transformation", 24 | "Data Transformation:", 25 | c("Daily" = "daily", "Weekly" = "weekly", "Cumulative" = "cumulative")), 26 | HTML("Created using the cranlogs package.", 27 | "This app is not affiliated with RStudio or CRAN.", 28 | "You can find the code for the app here,", 29 | "or read more about it here.") 30 | ), 31 | 32 | # Show a plot of the generated distribution 33 | mainPanel( 34 | plotOutput("downloadsPlot") 35 | ) 36 | ) 37 | )) 38 | --------------------------------------------------------------------------------