<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/one-r-package-a-day/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://stevenmortimer.com/one-r-package-a-day/"> stevenmortimer.com</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<div>
<img src="https://i0.wp.com/stevenmortimer.com/blog/one-r-package-a-day/profile-pic.png?w=456&ssl=1" data-recalc-dims="1">
</div>
<p>Discover one R package a day by following the <a rel="nofollow" href="https://twitter.com/RLangPackage" target="_blank"><span>@RLangPackage</span></a> account on Twitter! Inspired by One R Tip Day (<a rel="nofollow" href="https://twitter.com/RLangTip" target="_blank"><span>@RLangTip</span></a>) I created a Twitter bot that will feature one package with its description and GitHub URL each day. The R programming language (referred to as <a rel="nofollow" href="https://twitter.com/hashtag/rstats" target="_blank">#rstats</a> on Twitter) now has over 12,600 packages. Tweeting one each day would take more than 34 years to get through them all and that doesn’t even consider the rapid growth of new packages as shown in this <a rel="nofollow" href="ttp://blog.revolutionanalytics.com/2017/01/cran-10000.html" target="_blank">post</a>.</p>
<div>
<img src="https://i2.wp.com/stevenmortimer.com/blog/one-r-package-a-day/r-package-growth.png?w=456&ssl=1" data-recalc-dims="1">
</div>
<p>The purpose of the <a rel="nofollow" href="https://twitter.com/RLangPackage" target="_blank"><span>@RLangPackage</span></a> Twitter account is to feature the diversity of packages that R has to offer. Most users have heard of <strong>ggplot2</strong> and <strong>dplyr</strong>, but there are thousands of other great packages waiting to be discovered. In order to highlight those I took a list of all packages on CRAN and filtered it down to ones with anywhere between 5,000 and 1,000,000 CRAN downloads. I then took a subset of that with anywhere between 10 and 1,000 stars on GitHub. I decided to focus on these mildly popular packages with source code hosted on GitHub so that I can embed the link in the tweet and promote packages with code that people have already started to explore. After following those subsetting rules, one package is selected at random after narrowing to a list of packages that haven’t already been tweeted. I am hosting the bot on Heroku and using Heroku Scheduler to send out a tweet each day at 10:30am UTC or 6:30am Eastern Time. Below the credits and resources is the sloppily written Python that’s currently being hosted on Heroku and executed.</p>
<div>
<h2>Credits</h2>
<p>I was found a couple different blog posts on creating a Twitter bot with R, namely <a rel="nofollow" href="https://medium.com/@randerson112358/create-a-twitter-bot-using-r-5a94f1b1b886" target="_blank">here</a> and <a rel="nofollow" href="https://rstudio-pubs-static.s3.amazonaws.com/54352_3afcd597884a4192b3361513f2d32699.html" target="_blank">here</a>, but they didn’t involve deploying on Heroku or another cloud service. However, there were plenty of Python based Twitter bot tutorials, so I took full advantage of them and went the Python route. Below is the host of resources I considered while figuring out how to deploy the app, what Twitter package to use, and some basic Python syntax which, embarrassingly, I should know by now. I think most users will gravitate towards the <strong>tweepy</strong> Python library but I found that it throws up an error when using it with Conda 3.6. The issue is documented on GitHub <a rel="nofollow" href="https://github.com/tweepy/tweepy/issues/894" target="_blank">https://github.com/tweepy/tweepy/issues/894</a>.</p>
<p><strong>Resources</strong></p>
<ul>
<li>Used as a general guide to deploying: <a rel="nofollow" href="http://briancaffey.github.io/2016/04/05/twitter-bot-tutorial.html" target="_blank">http://briancaffey.github.io/2016/04/05/twitter-bot-tutorial.html</a></li>
<li>Setting up credentials as config vars: <a rel="nofollow" href="https://devcenter.heroku.com/articles/config-vars" target="_blank">https://devcenter.heroku.com/articles/config-vars</a></li>
<li>How to load environment vars from file: <a rel="nofollow" href="https://robinislam.me/blog/reading-environment-variables-in-python/" target="_blank">https://robinislam.me/blog/reading-environment-variables-in-python/</a></li>
<li>Timeline dump code: <a rel="nofollow" href="https://github.com/geduldig/TwitterAPI/blob/master/examples/dump_timeline.py" target="_blank">https://github.com/geduldig/TwitterAPI/blob/master/examples/dump_timeline.py</a></li>
</ul>
</div>
<div>
<h2>Full Script</h2>
<pre><code># script.py
from os import environ
from os.path import join, dirname
from dotenv import load_dotenv
from re import sub
import pandas
from TwitterAPI import TwitterAPI, TwitterPager

# create .env file path
dotenv_path = join(dirname(__file__), '.env')

# load file from the path
load_dotenv(dotenv_path)

if __name__ == &quot;__main__&quot;:

    # connect to api
    api = TwitterAPI(consumer_key=environ['TWITTER_CONSUMER_KEY'],
                     consumer_secret=environ['TWITTER_CONSUMER_SECRET'],
                     access_token_key=environ['TWITTER_ACCESS_TOKEN'],
                     access_token_secret=environ['TWITTER_ACCESS_TOKEN_SECRET'])

    # scrape all prior tweets to check which packages I've already tweeted about
    SCREEN_NAME = 'RLangPackage'
    pager = TwitterPager(api,
                         'statuses/user_timeline',
                         {'screen_name': SCREEN_NAME, 'count': 100})

    # parse out the package name that occurs before the hyphen at the beginning
    previous_pks = []
    for item in pager.get_iterator(wait=3.5):
        if 'text' in item:
            this_pkg = sub(&quot;^(\w+) - (.*)&quot;, &quot;\\1&quot;, item['text'])
            previous_pks.append(this_pkg)

    # convert the package names to a dataframe
    prev_df = pandas.DataFrame({'name': previous_pks})
    prev_df.set_index('name')

    # load the data I've compiled on R packages
    url = &quot;https://raw.githubusercontent.com/StevenMMortimer/one-r-package-a-day/master/r-package-star-download-data.csv&quot;
    all_df = pandas.read_csv(url)
    all_df.set_index('name')

    # do an &quot;anti join&quot; to throw away previously tweeted rows
    all_df = pandas.merge(all_df, prev_df, how='outer', indicator=True)
    all_df = all_df[all_df['_merge'] == 'left_only']

    # focus on packages in middle ground of downloads and stars
    filtered_df = all_df[all_df['stars'].notnull()]
    filtered_df = filtered_df[filtered_df['stars'].between(10,1000)]
    filtered_df = filtered_df[filtered_df['downloads'].notnull()]
    filtered_df = filtered_df[filtered_df['downloads'].between(5000, 1000000)]

    # randomly select one of the remaining rows
    selected_pkg = filtered_df.sample(1)

    # pull out the name and description to see if we need to 
    # truncate because of Twitters 280 character limit
    prepped_name = selected_pkg.iloc[0]['name']
    prepped_desc = sub('\s+', ' ', selected_pkg.iloc[0]['description'])

    name_len = len(prepped_name)
    desc_len = len(prepped_desc)

    # 280 minus 3 for &quot; - &quot;, then minus 23 because links are counted as such,
    # then minus 9 for the &quot; #rstats &quot; hashtag
    if desc_len &lt;= (280-3-23-9-name_len):
        prepped_desc = prepped_desc[0:desc_len]
    else:
        prepped_desc = prepped_desc[0:(280-6-23-9-name_len)] + &quot;...&quot;

    # cobble together the tweet text
    TWEET_TEXT = prepped_name + &quot; - &quot; + prepped_desc + &quot; #rstats &quot; + selected_pkg.iloc[0]['github_url']
    print(TWEET_TEXT)

    # tweet it out to the world!
    r = api.request('statuses/update', {'status': TWEET_TEXT})
    print('SUCCESS' if r.status_code == 200 else 'PROBLEM: ' + r.text)</code></pre>
</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/one-r-package-a-day/"> 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/XWwralD7O2E" height="1"></a></div>