<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/most-starred-r-packages-on-github/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://stevenmortimer.com/most-starred-r-packages-on-github"> Blog-rss on stevenmortimer.com</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p></p>
<div>
<img src="https://i2.wp.com/stevenmortimer.com/blog/most-starred-r-packages-on-github/star-download-relationship.png?w=456&ssl=1" data-recalc-dims="1">
</div>
<p>It seems like all the best R packages proudly use GitHub and have a README adorned with badges across the top. The recent <a rel="nofollow" href="https://techcrunch.com/2018/06/04/microsoft-has-acquired-github-for-7-5b-in-microsoft-stock/" target="_blank">Microsoft acquisition of GitHub</a> got me wondering: What proportion of current R packages use GitHub? Or at least refer to it in the URL of the package description. Also, what is the relationship between the number of CRAN downloads and the number of stars on a repository? My curiosity got the best of me so I hastily wrote a script to pull the data. Click <a rel="nofollow" href="https://stevenmortimer.com/most-starred-r-packages-on-github#full-script" target="_blank">here</a> to go straight to the full script and data included at the bottom of this post. I acknowledge there are more elegant ways to have coded this, but let’s press on.</p>
<div>
<h2>Pulling List of Packages &amp; their Details</h2>
<p>CRAN provides a list and links to all current packages at <a rel="nofollow" href="https://cran.rstudio.com/src/contrib" target="_blank">https://cran.rstudio.com/src/contrib</a>. By scraping this page I found 12,675 current R packages (non-archived). For each package I pinged its detail page using the canonical form link (e.g. <a rel="nofollow" href="https://cran.r-project.org/package=ggplot2" target="_blank">https://cran.r-project.org/package=ggplot2</a>). From there I looked at the package description fields <code>&quot;URL&quot;</code> and <code>&quot;BugReports&quot;</code> to see if either contained “github.com”. It turns out that 3,718 of the packages (29.3% of the total) referenced GitHub. Below is the code snippet for retrieving the list of packages that was taken from Gergely Daróczi’s <a rel="nofollow" href="https://gist.github.com/daroczig/3cf06d6db4be2bbe3368" target="_blank">gist</a>.</p>
<pre><code># getting list of the packages
pkgs &lt;- readHTMLTable(readLines(file.path('https://cran.rstudio.com/src/contrib')),
                      which = 1, 
                      stringsAsFactors = FALSE)[,-1]

# filter out lines that aren't really packages
pkgs &lt;- pkgs %>% 
  filter(Size != &quot;-&quot;, 
         grepl('tar.gz$', Name)) %>%
  mutate(Name = sub('^([a-zA-Z0-9\\.]*).*', '\\1', Name))</code></pre>
<p>While retrieving the package metadata I pinged the GitHub API to see if I could get the number of stars for the repository. Currently, GitHub allows 5,000 authenticated requests per hour <a rel="nofollow" href="https://developer.github.com/v3/#rate-limiting" target="_blank">(link)</a>, but out of all the packages only 3,718 referenced GitHub, so I could make all the requests at once. Here is the function I used to take a cleaned up version of the package’s URL then form a request to the GitHub API to get star counts:</p>
<pre><code># get the star count from a clean version of the package's URL
gh_star_count &lt;- function(url){
  stars  &lt;- tryCatch({
    this_url &lt;- gsub(&quot;https://github.com/&quot;, &quot;https://api.github.com/repos/&quot;, url)
    req &lt;- GET(this_url, gtoken)
    stop_for_status(req)
    cont &lt;- content(req)
    cont$stargazers_count  
  }, error = function(e){
    return(NA_integer_)
  })
  return(stars)
}</code></pre>
</div>
<div>
<h2>Analyzing the Data</h2>
<p>Once I had all the package detail data, I found that R packages, on average, have 35.7 GitHub stars, but the median number of stars is only 6! <strong>ggplot2</strong> has the most stars with 3,174. In my analysis I removed the <strong>xgboost</strong>, <strong>h2o</strong>, and <strong>feather</strong> packages which point to the repository of their implementations in many languages, not just R.</p>
<div>
<img src="https://i0.wp.com/stevenmortimer.com/blog/most-starred-r-packages-on-github/star-distribution.png?w=456&ssl=1" data-recalc-dims="1">
</div>
<p>What I really found interesting was comparing CRAN downloads to GitHub repo stars. Using the <strong>cranlogs</strong> package I was able to get the total package downloads dating back to January 1, 2014. In contrast with the low star counts, the median downloads for R packages is 8,975. Combining stars and downloads data I found that the median R package has 903 downloads per star. Only 38.7% of packages had more than 10 stars, which shows how hard stars are to get even if you’ve written a great package. I’m not sure what proportion of R users frequently reference and contribute to GitHub, but it would be interesting to compare that with the high ratios of downloads to stars.</p>
<div>
<img src="https://i1.wp.com/stevenmortimer.com/blog/most-starred-r-packages-on-github/star-download-scatter.png?w=456&ssl=1" data-recalc-dims="1">
</div>
<p>There are some real outliers in the data. For example, the <strong>Rcpp</strong> package, perhaps the most downloaded package of all-time, has 15.8M downloads and only 377 stars. Similarly, Hadley’s <strong>scales</strong> package has 9.4M downloads and only 115 stars. These support/helper packages just don’t get the same star love as the headliners like <strong>ggplot2</strong>, <strong>shiny</strong>, and <strong>dplyr</strong>.</p>
<p>Of course, I could not help but check out the stats for some of the most prolific package authors. After parsing out individuals with the <code>[&quot;aut&quot;, &quot;cre&quot;]</code> roles I came to the not so surprising conclusion that Hadley has the most stars of any author with 12,408 stars. In contrast, Dirk Eddelbuettel had one of the lowest star-to-download ratios. For every ~38K downloads Dirk’s repositories will receive one star. Pay no attention to the man behind the curtain since his <strong>Rcpp</strong> package underpins a whole host of packages without all the GitHub fanfare. Here is a list of popular R package authors and their stats:</p>
<table>
<thead>
<tr>
<th>
Author
</th>
<th>
Notable Packages
</th>
<th>
Downloads
</th>
<th>
Stars
</th>
<th>
Downloads Per Star
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Hadley Wickham
</td>
<td>
ggplot2, dplyr, httr
</td>
<td>
113,160,314
</td>
<td>
12,408
</td>
<td>
9,119.9
</td>
</tr>
<tr>
<td>
Dirk Eddelbuettel
</td>
<td>
Rcpp, BH
</td>
<td>
28,433,586
</td>
<td>
745
</td>
<td>
38,165.9
</td>
</tr>
<tr>
<td>
Yihui Xie
</td>
<td>
knitr, rmarkdown, bookdown
</td>
<td>
42,472,860
</td>
<td>
6,315
</td>
<td>
6,725.7
</td>
</tr>
<tr>
<td>
Winston Chang
</td>
<td>
R6, shiny
</td>
<td>
17,161,005
</td>
<td>
4,027
</td>
<td>
4,261.5
</td>
</tr>
<tr>
<td>
Jennifer Bryan
</td>
<td>
readxl, gapminder, googlesheets
</td>
<td>
6,055,774
</td>
<td>
1,714
</td>
<td>
3,533.1
</td>
</tr>
<tr>
<td>
JJ Allaire
</td>
<td>
rstudioapi, reticulate, tensorflow
</td>
<td>
8,882,553
</td>
<td>
2,798
</td>
<td>
3,174.6
</td>
</tr>
<tr>
<td>
Jeroen Ooms
</td>
<td>
jsonlite, curl, openssl
</td>
<td>
25,907,868
</td>
<td>
1,483
</td>
<td>
17,469.9
</td>
</tr>
<tr>
<td>
Scott Chamberlain
</td>
<td>
geojsonio, taxize
</td>
<td>
1,770,664
</td>
<td>
2,528
</td>
<td>
700.4
</td>
</tr>
<tr>
<td>
Jim Hester
</td>
<td>
devtools, memoise, readr
</td>
<td>
22,867,071
</td>
<td>
4,332
</td>
<td>
5,278.6
</td>
</tr>
<tr>
<td>
Kirill Müller
</td>
<td>
tibble, DBI
</td>
<td>
36,159,009
</td>
<td>
1,077
</td>
<td>
33,573.8
</td>
</tr>
</tbody>
</table>
<p>I’m sure you could create mixed models to determine the unique download to star relationship for individuals. Also, you could use other package attributes to predict stars or downloads, but I’ll leave that to another curious soul. I will include tables below regarding the top 10 most downloaded, most starred, most and least downloaded per star.</p>
</div>
<div>
<h2>Credits</h2>
<p>Credit is due since this script borrows a couple different pieces of code and concepts. Retrieving the list of packages is from Gergely Daróczi’s <a rel="nofollow" href="https://gist.github.com/daroczig/3cf06d6db4be2bbe3368" target="_blank">gist</a>. Authenticating to GitHub was taken from one of the <strong>httr</strong> <a rel="nofollow" href="https://github.com/r-lib/httr/blob/master/demo/oauth2-github.r" target="_blank">demos</a>.</p>
</div>
<div>
<h2>Appendix</h2>
<div>
<h3>Top 10 Most Starred Packages</h3>
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
Author
</th>
<th>
Downloads
</th>
<th>
Stars
</th>
<th>
Downloads Per Star
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
ggplot2
</td>
<td>
Hadley Wickham
</td>
<td>
13,001,703
</td>
<td>
3,174
</td>
<td>
4,096.3
</td>
</tr>
<tr>
<td>
shiny
</td>
<td>
Winston Chang
</td>
<td>
4,571,794
</td>
<td>
2,902
</td>
<td>
1,575.4
</td>
</tr>
<tr>
<td>
dplyr
</td>
<td>
Hadley Wickham
</td>
<td>
8,276,844
</td>
<td>
2,408
</td>
<td>
3,437.2
</td>
</tr>
<tr>
<td>
devtools
</td>
<td>
Jim Hester
</td>
<td>
5,536,730
</td>
<td>
1,645
</td>
<td>
3,365.8
</td>
</tr>
<tr>
<td>
knitr
</td>
<td>
Yihui Xie
</td>
<td>
7,131,564
</td>
<td>
1,581
</td>
<td>
4,510.8
</td>
</tr>
<tr>
<td>
data.table
</td>
<td>
Matt Dowle
</td>
<td>
6,005,795
</td>
<td>
1,457
</td>
<td>
4,122.0
</td>
</tr>
<tr>
<td>
plotly
</td>
<td>
Carson Sievert
</td>
<td>
1,195,880
</td>
<td>
1,255
</td>
<td>
952.9
</td>
</tr>
<tr>
<td>
rmarkdown
</td>
<td>
Yihui Xie
</td>
<td>
5,432,495
</td>
<td>
1,160
</td>
<td>
4,683.2
</td>
</tr>
<tr>
<td>
tensorflow
</td>
<td>
JJ Allaire
</td>
<td>
94,856
</td>
<td>
1,033
</td>
<td>
91.8
</td>
</tr>
<tr>
<td>
bookdown
</td>
<td>
Yihui Xie
</td>
<td>
126,586
</td>
<td>
1,009
</td>
<td>
125.5
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h3>Top 10 Most Downloaded Packages with Stars</h3>
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
Author
</th>
<th>
Downloads
</th>
<th>
Stars
</th>
<th>
Downloads Per Star
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Rcpp
</td>
<td>
Dirk Eddelbuettel
</td>
<td>
15,824,781
</td>
<td>
377
</td>
<td>
41,975.5
</td>
</tr>
<tr>
<td>
ggplot2
</td>
<td>
Hadley Wickham
</td>
<td>
13,001,703
</td>
<td>
3,174
</td>
<td>
4,096.3
</td>
</tr>
<tr>
<td>
stringr
</td>
<td>
Hadley Wickham
</td>
<td>
11,547,828
</td>
<td>
268
</td>
<td>
43,088.9
</td>
</tr>
<tr>
<td>
stringi
</td>
<td>
Marek Gagolewski
</td>
<td>
11,310,113
</td>
<td>
122
</td>
<td>
92,705.8
</td>
</tr>
<tr>
<td>
digest
</td>
<td>
Dirk Eddelbuettel with contributions by Antoine Lucas
</td>
<td>
11,233,244
</td>
<td>
42
</td>
<td>
267,458.2
</td>
</tr>
<tr>
<td>
plyr
</td>
<td>
Hadley Wickham
</td>
<td>
10,340,396
</td>
<td>
470
</td>
<td>
22,000.8
</td>
</tr>
<tr>
<td>
R6
</td>
<td>
Winston Chang
</td>
<td>
9,993,128
</td>
<td>
212
</td>
<td>
47,137.4
</td>
</tr>
<tr>
<td>
reshape2
</td>
<td>
Hadley Wickham
</td>
<td>
9,582,245
</td>
<td>
173
</td>
<td>
55,388.7
</td>
</tr>
<tr>
<td>
scales
</td>
<td>
Hadley Wickham
</td>
<td>
9,380,757
</td>
<td>
115
</td>
<td>
81,571.8
</td>
</tr>
<tr>
<td>
jsonlite
</td>
<td>
Jeroen Ooms
</td>
<td>
9,112,790
</td>
<td>
176
</td>
<td>
51,777.2
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h3>Top 10 Packages by Stars per Download (frequently starred)</h3>
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
Author
</th>
<th>
Downloads
</th>
<th>
Stars
</th>
<th>
Downloads Per Star
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
r2d3
</td>
<td>
Javier Luraschi
</td>
<td>
416
</td>
<td>
235
</td>
<td>
1.77
</td>
</tr>
<tr>
<td>
workflowr
</td>
<td>
John Blischak
</td>
<td>
448
</td>
<td>
169
</td>
<td>
2.65
</td>
</tr>
<tr>
<td>
goodpractice
</td>
<td>
Hannah Frick
</td>
<td>
523
</td>
<td>
192
</td>
<td>
2.72
</td>
</tr>
<tr>
<td>
xtensor
</td>
<td>
Johan Mabille
</td>
<td>
2,057
</td>
<td>
664
</td>
<td>
3.10
</td>
</tr>
<tr>
<td>
scico
</td>
<td>
Thomas Lin Pedersen
</td>
<td>
185
</td>
<td>
59
</td>
<td>
3.14
</td>
</tr>
<tr>
<td>
shinytest
</td>
<td>
Winston Chang
</td>
<td>
418
</td>
<td>
113
</td>
<td>
3.70
</td>
</tr>
<tr>
<td>
furrr
</td>
<td>
Davis Vaughan
</td>
<td>
724
</td>
<td>
171
</td>
<td>
4.23
</td>
</tr>
<tr>
<td>
pkgdown
</td>
<td>
Hadley Wickham
</td>
<td>
1,589
</td>
<td>
332
</td>
<td>
4.79
</td>
</tr>
<tr>
<td>
rtika
</td>
<td>
Sasha Goodman
</td>
<td>
168
</td>
<td>
32
</td>
<td>
5.25
</td>
</tr>
<tr>
<td>
mindr
</td>
<td>
Peng Zhao
</td>
<td>
2,051
</td>
<td>
368
</td>
<td>
5.57
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h3>Bottom 10 Packages by Stars per Download (infrequently starred)</h3>
<table>
<thead>
<tr>
<th>
Name
</th>
<th>
Author
</th>
<th>
Downloads
</th>
<th>
Stars
</th>
<th>
Downloads Per Star
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
mime
</td>
<td>
Yihui Xie
</td>
<td>
7,398,765
</td>
<td>
12
</td>
<td>
616,563.8
</td>
</tr>
<tr>
<td>
pkgmaker
</td>
<td>
Renaud Gaujoux
</td>
<td>
1,228,173
</td>
<td>
2
</td>
<td>
614,086.5
</td>
</tr>
<tr>
<td>
rngtools
</td>
<td>
Renaud Gaujoux
</td>
<td>
1,224,959
</td>
<td>
2
</td>
<td>
612,479.5
</td>
</tr>
<tr>
<td>
magic
</td>
<td>
Robin K. S. Hankin
</td>
<td>
344,741
</td>
<td>
1
</td>
<td>
344,741.0
</td>
</tr>
<tr>
<td>
gsubfn
</td>
<td>
G. Grothendieck
</td>
<td>
675,056
</td>
<td>
2
</td>
<td>
337,528.0
</td>
</tr>
<tr>
<td>
bindrcpp
</td>
<td>
Kirill Müller
</td>
<td>
2,996,452
</td>
<td>
10
</td>
<td>
299,645.2
</td>
</tr>
<tr>
<td>
plogr
</td>
<td>
Kirill Müller
</td>
<td>
3,343,099
</td>
<td>
12
</td>
<td>
278,591.6
</td>
</tr>
<tr>
<td>
digest
</td>
<td>
Dirk Eddelbuettel with contributions by Antoine Lucas
</td>
<td>
11,233,244
</td>
<td>
42
</td>
<td>
267,458.2
</td>
</tr>
<tr>
<td>
munsell
</td>
<td>
Charlotte Wickham
</td>
<td>
7,778,712
</td>
<td>
31
</td>
<td>
250,926.2
</td>
</tr>
<tr>
<td>
proto
</td>
<td>
Hadley Wickham
</td>
<td>
2,593,246
</td>
<td>
11
</td>
<td>
235,749.6
</td>
</tr>
</tbody>
</table>
</div>
<div>
<h3>Full Script</h3>
<p>Below and available via gist with data at: <a rel="nofollow" href="https://gist.github.com/StevenMMortimer/1b4b626d3d91240a77f969ae04b37114" target="_blank">https://gist.github.com/StevenMMortimer/1b4b626d3d91240a77f969ae04b37114</a></p>
<pre><code># load packages &amp; custom functions ---------------------------------------------

library(tidyverse)
library(httr)
library(cranlogs)
library(XML)
library(ggrepel)
library(scales)
library(knitr)
library(stringr)

gh_from_url &lt;- function(x){
  if(!grepl(',', x)){
    x &lt;- strsplit(x, &quot; &quot;)[[1]]
    x &lt;- trimws(x[min(which(grepl(pattern='http://github.com|https://github.com|http://www.github.com', x, ignore.case=TRUE)))])    
  } else {
    x &lt;- strsplit(x, &quot;,&quot;)[[1]]
    x &lt;- trimws(x[min(which(grepl(pattern='http://github.com|https://github.com|http://www.github.com', x, ignore.case=TRUE)))])    
  }
  x &lt;- gsub(&quot;http://&quot;, &quot;https://&quot;, tolower(x))
  x &lt;- gsub(&quot;www\\.github\\.com&quot;, &quot;github.com&quot;, x)
  x &lt;- gsub(&quot;/$&quot;, &quot;&quot;, x)
  x &lt;- gsub(&quot;^github.com&quot;, &quot;https://github.com&quot;, x)
  x &lt;- gsub(&quot;/issues&quot;, &quot;&quot;, x)
  x &lt;- gsub(&quot;\\.git&quot;, &quot;&quot;, x)
  return(x)
}

aut_maintainer_from_details &lt;- function(x){
  x &lt;- gsub(&quot;'|\&quot;&quot;, &quot;&quot;, x)
  if(grepl(',', x)){
    x &lt;- strsplit(x, &quot;\\],&quot;)[[1]]
    aut_cre_ind &lt;- grepl(pattern='\\[aut, cre|\\[cre, aut|\\[cre', x, ignore.case=TRUE)
    if(any(aut_cre_ind)){
      x &lt;- x[min(which(aut_cre_ind))]
      x &lt;- gsub(&quot;\\[aut, cre|\\[cre, aut|\\[cre&quot;, &quot;&quot;, x)
    }
    x &lt;- strsplit(x, &quot;,&quot;)[[1]][1]
    x &lt;- trimws(gsub(&quot;\\]&quot;, &quot;&quot;, x))
    x &lt;- trimws(gsub(&quot; \\[aut&quot;, &quot;&quot;, x))
  }
  return(x)
}

gh_star_count &lt;- function(url){
  stars  &lt;- tryCatch({
    this_url &lt;- gsub(&quot;https://github.com/&quot;, &quot;https://api.github.com/repos/&quot;, url)
    req &lt;- GET(this_url, gtoken)
    stop_for_status(req)
    cont &lt;- content(req)
    cont$stargazers_count  
  }, error = function(e){
    return(NA_integer_)
  })
  return(stars)
}

# authenticate to github -------------------------------------------------------
# use Hadley's key and secret
myapp &lt;- oauth_app(&quot;github&quot;,
                   key = &quot;56b637a5baffac62cad9&quot;,
                   secret = &quot;8e107541ae1791259e9987d544ca568633da2ebf&quot;)
github_token &lt;- oauth2.0_token(oauth_endpoints(&quot;github&quot;), myapp)
gtoken &lt;- config(token = github_token)

# pull list of packages --------------------------------------------------------

# get list of currently available packages on CRAN
pkgs &lt;- readHTMLTable(readLines(file.path('https://cran.rstudio.com/src/contrib')),
                      which = 1, 
                      stringsAsFactors = FALSE)[,-1]

# filter out lines that aren't really packages
pkgs &lt;- pkgs %>% 
  filter(Size != &quot;-&quot;, 
         grepl('tar.gz$', Name)) %>%
  mutate(Name = sub('^([a-zA-Z0-9\\.]*).*', '\\1', Name)) %>%
  distinct(Name, .keep_all = TRUE)

# get details for each package -------------------------------------------------

all_pkg_details &lt;- NULL

# old fashioned looping! 
# WARNING: This takes awhile to complete
for(i in 1:nrow(pkgs)){
  
  if(i %% 100 == 0){
    message(sprintf(&quot;Processing package #%s out of %s&quot;, i, nrow(pkgs)))
  }
  
  pkg_details &lt;- readHTMLTable(readLines(file.path(sprintf('https://cran.r-project.org/package=%s', pkgs[i,]$Name))), 
                               header=FALSE, 
                               which = 1, 
                               stringsAsFactors = FALSE)
  pkg_details &lt;- pkg_details %>%
    mutate(V1 = gsub(&quot;:&quot;, &quot;&quot;, V1)) %>%
    spread(V1, V2)
  
  this_url &lt;- pkg_details$URL
  on_github &lt;- FALSE
  this_github_url &lt;- NA_character_
  gh_stars &lt;- NA_integer_
  if(!is.null(this_url)){
    on_github &lt;- grepl('http://github.com|https://github.com|http://www.github.com', this_url)
    if(on_github){
      this_github_url &lt;- gh_from_url(this_url)
      gh_stars &lt;- gh_star_count(this_github_url)
    } else {
      # check the BugReports URL as a backup (e.g. shiny package references GitHub this way)
      issues_on_github &lt;- grepl('http://github.com|https://github.com|http://www.github.com', pkg_details$BugReports)
      if(length(issues_on_github) == 0 || !issues_on_github){
        this_github_url &lt;- NA_character_
      } else {
        this_github_url &lt;- gh_from_url(pkg_details$BugReports)
        gh_stars &lt;- gh_star_count(this_github_url)  
        on_github &lt;- TRUE
      }
    }
  } else {
    this_url &lt;- NA_character_
  }
  
  downloads &lt;- cran_downloads(pkgs[i,]$Name, from = &quot;2014-01-01&quot;, to = &quot;2018-06-15&quot;)
  
  all_pkg_details &lt;- rbind(all_pkg_details, 
                           tibble(name = pkgs[i,]$Name, 
                                  published = pkg_details$Published,
                                  author = aut_maintainer_from_details(pkg_details$Author),
                                  url = this_url,
                                  github_ind = on_github, 
                                  github_url = this_github_url,
                                  downloads = sum(downloads$count),
                                  stars = gh_stars
                           )
  )
}

# basic summary stats ----------------------------------------------------------

# remove observations where the GitHub URL refers to a repository that 
# is not specific to R and therefore might have an inflated star count
all_pkg_details_clean &lt;- all_pkg_details %>% 
  filter(!(name %in% c('xgboost', 'h2o', 'feather'))) %>% 
  mutate(downloads_per_star = downloads / stars, 
         downloads_per_star = ifelse(!is.finite(downloads_per_star), NA_real_, downloads_per_star))

# proportion of all packages listing github
sum(all_pkg_details$github_ind)
mean(all_pkg_details$github_ind)
# proportion of packages with stars
mean(!is.na(all_pkg_details$stars))

# typical number of stars per package
mean(all_pkg_details_clean$stars, na.rm=TRUE)
median(all_pkg_details_clean$stars, na.rm=TRUE)
max(all_pkg_details_clean$stars, na.rm=TRUE)

# typical number of downloads per package
mean(all_pkg_details_clean$downloads, na.rm=TRUE)
median(all_pkg_details_clean$downloads, na.rm=TRUE)

# percent of packages over 10 stars
mean(all_pkg_details_clean$stars > 10, na.rm=TRUE)

mean(all_pkg_details_clean$downloads_per_star, na.rm=TRUE)
median(all_pkg_details_clean$downloads_per_star, na.rm=TRUE)


# stars histogram --------------------------------------------------------------
ggplot(data=all_pkg_details_clean, mapping=aes(stars)) +
  geom_histogram(aes(fill=..count..), bins=60) +
  scale_x_continuous(trans = &quot;log1p&quot;, breaks=c(0,1,2,3,10,100,1000,3000)) + 
  labs(x = &quot;Stars&quot;, 
       y = &quot;Count&quot;, 
       fill = &quot;Count&quot;, 
       caption = &quot;Source: api.github.com as of 6/16/18&quot;) + 
  ggtitle(&quot;Distribution of GitHub Stars on R Packages&quot;) + 
  theme_bw() + 
  theme(panel.grid.minor = element_blank(), 
        plot.caption=element_text(hjust = 0))

# stars to downloads scatterplot -----------------------------------------------
plot_dat &lt;- all_pkg_details_clean
idx_label &lt;- which(with(plot_dat, downloads > 10000000 | stars > 1000))
plot_dat$name2 &lt;- plot_dat$name
plot_dat$name &lt;- &quot;&quot;
plot_dat$name[idx_label] &lt;- plot_dat$name2[idx_label]

ggplot(data=plot_dat, aes(stars, downloads, label = name)) +
  geom_point(color = ifelse(plot_dat$name == &quot;&quot;, &quot;grey50&quot;, &quot;red&quot;)) +
  geom_text_repel(box.padding = .5) + 
  scale_y_continuous(labels = comma) + 
  scale_x_continuous(labels = comma) + 
  labs(x = &quot;GitHub Stars&quot;, 
       y = &quot;CRAN Downloads&quot;, 
       caption = &quot;Sources:\napi.github.com as of 6/16/18\ncranlogs as of 1/1/14 - 6/15/18&quot;) + 
  ggtitle(&quot;Relationship Between CRAN Downloads and GitHub Stars&quot;) + 
  theme_bw() + 
  theme(plot.caption=element_text(hjust = 0))

# author stats -----------------------------------------------------------------

# summary by author
authors_detail &lt;- all_pkg_details_clean %>% 
  group_by(author) %>% 
  summarize(downloads = sum(downloads, na.rm=TRUE), 
            stars = sum(stars, na.rm=TRUE)) %>% 
  mutate(downloads_per_star = downloads / stars, 
         downloads_per_star = ifelse(!is.finite(downloads_per_star), NA_real_, downloads_per_star)) %>% 
  arrange(desc(downloads))

# popular authors
pop_authors &lt;- tibble(author = c('Hadley Wickham', 
                                 'Dirk Eddelbuettel', 
                                 'Yihui Xie', 
                                 'Winston Chang', 
                                 'Jennifer Bryan', 
                                 'JJ Allaire',
                                 'Jeroen Ooms', 
                                 'Scott Chamberlain', 
                                 'Jim Hester', 
                                 'Kirill Müller'), 
                      notable_packages = c('ggplot2, dplyr, httr',
                                           'Rcpp, BH', 
                                           'knitr, rmarkdown, bookdown', 
                                           'R6, shiny', 
                                           'readxl, gapminder, googlesheets', 
                                           'rstudioapi, reticulate, tensorflow', 
                                           'jsonlite, curl, openssl', 
                                           'geojsonio, taxize', 
                                           'devtools, memoise, readr', 
                                           'tibble, DBI')
)
author_stats &lt;- pop_authors %>% 
  inner_join(., authors_detail, by='author') %>%
  select(author, notable_packages, downloads, stars, downloads_per_star) %>% 
  mutate(downloads_per_star = round(downloads_per_star, 1)) %>%
  rename_all(. %>% gsub(&quot;_&quot;, &quot; &quot;, .) %>% str_to_title)

# single author 
#all_pkg_details_clean %>% filter(author == 'Dirk Eddelbuettel') %>% arrange(desc(downloads))  

# top 10 lists -----------------------------------------------------------------

# Top 10 Most Starred Packages

top_starred &lt;- all_pkg_details_clean %>% 
  select(name, author, downloads, stars, downloads_per_star) %>%
  arrange(desc(stars)) %>%
  slice(1:10) %>% 
  mutate(downloads_per_star = round(downloads_per_star, 1)) %>%
  rename_all(. %>% gsub(&quot;_&quot;, &quot; &quot;, .) %>% str_to_title)

# Top 10 Most Downloaded Packages with stars

top_downloaded &lt;- all_pkg_details_clean %>% 
  filter(!is.na(stars)) %>%
  select(name, author, downloads, stars, downloads_per_star) %>%
  arrange(desc(downloads)) %>%
  slice(1:10) %>% 
  mutate(downloads_per_star = round(downloads_per_star, 1)) %>%
  rename_all(. %>% gsub(&quot;_&quot;, &quot; &quot;, .) %>% str_to_title)

# Bottom 10 Packages by Downloads per Star (frequently starred) 

frequently_starred &lt;- all_pkg_details_clean %>% 
  filter(downloads > 100) %>% 
  select(name, author, downloads, stars, downloads_per_star) %>%
  arrange(downloads_per_star) %>%
  slice(1:10) %>% 
  mutate(downloads_per_star = round(downloads_per_star, 2)) %>%
  rename_all(. %>% gsub(&quot;_&quot;, &quot; &quot;, .) %>% str_to_title)

# Top 10 Packages by Downloads per Star (infrequently starred) 

infrequently_starred &lt;- all_pkg_details_clean %>% 
  select(name, author, downloads, stars, downloads_per_star) %>%
  arrange(desc(downloads_per_star)) %>%
  slice(1:10) %>% 
  rename_all(. %>% gsub(&quot;_&quot;, &quot; &quot;, .) %>% str_to_title)</code></pre>
</div>
</div>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://stevenmortimer.com/most-starred-r-packages-on-github"> Blog-rss on stevenmortimer.com</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/nzJ_A2m_RGA" height="1"></a></div>