├── .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 |
--------------------------------------------------------------------------------