Twitter Activity around the Bayer + Monsanto Merger Announcement
As is usual for me, code outside of work comes out of curiosity.
I’ve always known that there is a lot of negativity in social media around Monsanto and GMO’s but I had no idea how much chatter there was about them. I started some code on this in late August and due to the continual talk around a merger with Bayer, I added them as a search term. While I still have data to look into determining the negativity vs. positivity used in tweets, I focused on frequency over time and words used around the merger announcement for this post.
I had done some data scraping before with Twitch Chat using python 3 and postgres to scrape data from public chat rooms. Since I already had some experience with python + postgres I opted to use a similar setup this time. Using tweepy I wrote a bot to stream tweets into a pg database on a spare laptop.
My pg database is setup on my laptop running linux mint but any OS/hardware should work in theory. My table definition is at create_table.sql.
main.py handles the scraping of data into the database. Below you can see the main loop portion where it runs try: on stream.filter() to stream the tweets with words of interest into the database. This is run simply with python main.py and left to run.
Once we have enough data we can actually look at it. For this I used R with ggplot2 to visualize my data.
tweet-viz.R holds all the code. It optionally can uncomment sourcing common-words.R to create a word cloud of the words used on the day of the merger announcement.
First the function get_data() is defined to pull all of the data out of our database. At the time of this post I was able to lazily get away with select * from tweets; due to the data being small enough and mostly in the time period of interest. In the future selecting the proper columns and limiting by a time range could be necessary.
Next we call the function and slim down our data set ensuring monsanto, bayer, and gmo are included in the tweet text and that the tweets happened the work week of the announcement. Lastly we determine the top 5 tweet languages used for graphing.
Now that we have our data the way we want it, we create 3 graphs.
Graph 1: Tweets by Language; A look into the variety in languages used in tweets English I expected as a top language but others I was interested to see. None were terribly surprising considering South American Agriculture (Spanish/Portuguese) and European interest in Bayer (German/French) but still interesting to see how it was distributed.
Graph 2: Tweets 9-11 to 9-16; A high level view of the amount of tweets written the work week of the announcement. Most activity was on the day of but a few small spikes happened days after.
Graph 3: Tweets on 9-14 - Merger Announced; The day of the announcement with a vertical bar for the timestamp of the tweet Monsanto sent out regarding it. Time is in the US Central Timezone (aka the timezone of Monsanto HQ).
The image produced by the above code is below.
Now that we know how many tweets were posted and what languages they were in, we can look into creating a word cloud of the words used to talk about the merger.
I had never done a word cloud in code before this. All my experience in word clouds was dropping chunks of text into online tools and then saving the image so this was a learning experience.
The code does similar filtering of the raw data from postgres and uses the tm package to remove common words we are not interested in viewing. Using dplyr & table the data is arranged and filtered down to the top 50 words and then visualized using wordcloud(). Depending on the resolution used the words can overlap or be spread to far apart. In Rstudio I had trouble using the plot pane to view my work as it was too small. Upon expanding it the words snapped into a good position. Not the greatest word cloud ever created but it’ll work. I decided to include numbers in mine as the specific number 66 was important as the number in billions that Bayer is paying for Monsanto.
At long last, here is our word cloud:
Below is the repository for the code I used in this post and the latest commit in case I make future changes that break code shown here. If you have any questions feel free to reach out on Twitter or by Email