2017.1017 Emojis of #MeToo (Top 20 Grouped)

Last month, I gave a talk 🗣️ at the 22×20 Planning Summit at the Brown Institute for Media Innovation at the Columbia Journalism School. The hall packed with media executives and journalists, mostly in their 30s and 40s, was initially full of grins 😂 but quickly turned thoughtful 🤔 as I walked them through my work in emoji data science.

I impressed upon them that while emojis might seem fun and trivial, they are at their core vessels for conveying human emotion. Anywhere we have a topic that people feel strongly about, we’re also likely to find an array of emojis that are used to accentuate and complement those feelings.

For example, this tweet from Election Night last year is my favorite response to people who think emojis are silly:

Consider how effectively and emotionally, in just 21 words and one emoji, the author captures the disappointment and malaise that so many of us experienced on Election Night. This is why emojis are important and this is why we study them.

Over the past few days, #MeToo has emerged as a viral social media trend used by women to express solidarity in the face of a culture of sexual harassment and assault. In the 24 hours after actress Alyssa Milano first tweeted about it last Sunday afternoon – piggybacking on a campaign started by activist Tarana Burke in 2007 – over 12 million people have posted on social media with the hashtag #MeToo.

We were curious about the emojis people were using when talking about #MeToo so we downloaded 28,629 English-language tweets from October 16 using the Twitter Search API. What did we find?

2017.1017 Emojis of #MeToo (Top 10 Horizontal).png

The top three emojis used with #MeToo are the ❤️ red heart, the 💔 broken heart, and the 😔 pensive face – conveying an emoji emotional signature of love, heartbreak, and disappointment. The 💜 purple heart and 💕 two hearts emojis also make an appearance in the top ten, along with the ✊ raised fist 💪 flexed biceps as shows of solidarity.

Only 5.2% of tweets with #MeToo include emojis, a much smaller percentage than we typically observe with most pop culture hashtags (for example, on a typical Wednesday, as many as 41% tweets with the hashtag #wcw included emojis). The proportion is, however, in the same 5-6% range we observed in our analysis of protest hashtags in February.

Here are the top 20 emojis of #MeToo:

Rank Emoji Emoji Name Frequency Per 1,000 Tweets
1 ❤️ red heart 9.0
2 💔 broken heart 4.1
3 😔 pensive face 2.5
4 😢 crying face 2.3
5 💜 purple heart 2.2
6 👇 backhand index pointing down 1.7
7 💕 two hearts 1.7
8 ✊ raised fist 1.6
9 💪 flexed biceps 1.6
10 😡 pouting face 1.6
11 😍 smiling face with heart-eyes 1.3
12 🙏 folded hands 1.3
13 💖 sparkling heart 1.1
14 💙 blue heart 1.0
15 😞 disappointed face 1.0
16 👏 clapping hands 1.0
17 💛 yellow heart 1.0
18 💗 growing heart 0.9
19 😕 confused face 0.7
20 😥 disappointed but relieved face 0.7

We find that 8 of the top 20 emojis of #MeToo are hearts, 7 are faces (1 positive and 6 negative) and 5 are hand gestures (4 positive and 1 neutral). Here is another way to to visualize these top 20 emojis, grouped by emoji type:

2017.1017 Emojis of #MeToo (Top 20 Grouped).png

What about skin tone distributions? Last year, Andrew McGill published the first quantitative analysis of skin tone emoji usage in The Atlantic in a piece entitled “Is It Okay to Use White Emoji?”. His main finding was that even though white Twitter users outnumber black Twitter users four-to-one, usage of the lightest skin emojis was far lower than one might expect, perhaps due to shame among white people or a desire not to be associated with white power.

The #MeToo movement too, despite its mass adoption, has faced some tension on the issue of race. Writing in Ebony, journalist Zahara Hill pointed out that the hashtag had originated with a black woman ten years ago. “A Black Woman Created the “Me Too” Campaign Against Sexual Assault 10 Years Ago…Yet, in the early conversations that spurred the “Me Too” movement, there was a sense it wasn’t for us,” she wrote.

Thus, we were justifiably curious about the distribution of skin tone emojis in tweets mentioning #MeToo. Using the linguist Kate Lyons’ updated emoji dictionary, we looked at the top 6 emojis in our dataset with the highest frequency of skin tone usage. Here’s what we found:

2017.1017 Emojis of #MeToo (Skin Tone Distributions)

The most common skin tone for these emojis – which all represent gestures – is always either Color 1 or Color 2. (Note that in the table above, we only look at emojis that use a skin tone modifier. The percent of usage for a given emoji that includes a skin tone modifier ranges from 34% for 👇 to 86% for 👊.)

We also find a gradation of emojis based on mean skin tone, with ✊ being the darkest, with a mean skin tone of 2.8, and 🖕 being the lightest, with a mean skin tone of 1.6. (Our numbers are in the same overall range as Andrew Sullivan’s analysis which finds a mean skin tone across all emojis of 2.4).

These are preliminary results, and likely are only meaningful if we compare skin tone emoji usage between multiple hashtags, but they hold promise for better understanding the nuances of our communication about race using emojis.

Enjoyed this analysis? Download the raw data for yourself at GitHub, check out our tutorial on emoji data science in R, and subscribe to our newsletter to keep up with the latest in emoji analysis.

By Hamdan Azhar

Some updates from PRISMOJI world:

  • Last week, The Stream on Al Jazeera broadcast an entire segment on emoji diversity and their role in popular culture. PRISMOJI founder Hamdan Azhar was one of the panelists, along with Emojipedia’s Jeremy Burge, linguist Gretchen McCulloch, and Kate Miltner of USC. Take a listen here!

 

  • We published an analysis of the top emojis of World Emoji Day! Check out the entire article on Emojipedia. We’re especially excited by our analysis of the top cat face emojis, which is the first research finding in this area to our meow-ledge.

Image7-TopEmojis-CatFaces.png

  • We’ve partnered with Grafiti and Polygraph to start a monthly Data Storytelling NYC Community Meetup! Check out the pictures from our first two events, and follow along with future events here!

IMG_7863e

🚨 Warning: Episode 1 & 2 Spoilers Ahead 🚨

The long awaited Game of Thrones has finally returned! If you’re a fan of the HBO show but don’t watch a new episode immediately, you likely stay clear of the Twitter world, for the net is dark and full of spoilers. So how did GoT fans react to the first two episodes on Twitter?

To answer that question, we downloaded 100,000 tweets for each trending hashtag or keyword related to Game of Thrones after a new episode aired. The hashtags and keywords we looked into included: #GameOfThrones, #WinterIsHere, #ThronesYall, Arya, Ed Sheehan, Sansa, Jon Snow, Daenerys, Cersei, Theon, Melisandre, Olenna, Greyworm, Ser Jorah, Euron, Nymeria, Hot Pie, Sand Snakes, and Gendry.

Let’s begin our deep dive, starting with episode 1: Dragonstone!

Nothing too crazy happened during the first episode… Except for the fact that Arya Stark wiped out an entire family!👏💪💀

Arya

We see positive emojis in reaction to Arya’s mass murder of the fam who betrayed her fam, as expected.

Yes, Game of Thrones was 🔥lit🔥 thanks to Arya. How are people using 😭 loudly crying face? Is the sentiment close to “I’m so proud of you, Arya!!” OR “OMG! Arya is turning into a monster!”

Arya is a hero; it is known. You go girl!👊

Ed Sheeran made a wild appearance alongside Arya, so naturally, we thought Ed Sheeran would be trending on Twitter. Instead, “Ed Sheehan” made a splash on the Twittersphere.

edsheehantrend

While our battery continued to die, we had to investigate!

EdSheehan

😂 face with tears of joy leads the way for “Ed Sheehan”. Were people making fun of this trend or were they actually misspelling his name repeatedly?

Looks like quite a few people don’t know how to spell Ed Sheeran… 😳 Maybe this contributed to Ed Sheeran’s decision to temporarily quit Twitter!

Moving onto the more recent, and arguably more exciting, episode 2: Stormborn!

Many things happened in this episode. Young lovers, much anticipated reunions, girl power, deadly diseases getting cured, family betrayal, and, of course, death.

Let’s start with our first reunion: Arya and Hot Pie!

HotPie

Lots of love here! ❤️ Do GoT fans think Arya and Hot Pie may make a fab couple?

“Can’t believe I thought you were a boy, you’re pretty!”

Maybe a handful think they’d be the ultimate OTP, but for the most part, GoT fans just ❤️ Hot Pie!

Second reunion: after 6 long seasons, Arya FINALLY reunites with her long-lost direwolf, Nymeria, but the reunion didn’t last long.

Nymeria

Many fans voiced that Arya and Nymeria’s quick separation was not expected, and that was reflected in the emojis used alongside Nymeria, with the exception of 😂.

While the majority of tweets echoed the following sentiment…

… a few fans decided to react with a more positive approach: humor! Here are a few highlights:

Beyond the heartwarming and heartbreaking reunions and badass moments from Arya Stark, there are many other characters on the TV show! In fact, there were quite a few girl power moments. As much as we may dislike Cersei, a queen is actually ruling Westeros. Other women are holding positions of power, from Daenerys Targaryen at Dragonstone to Sansa Stark in Winterfell. There’s even a scene with a handful of women warriors at battle. R.I.P. ⚰️

Also, Daenerys Targaryen gets a female role model: Olenna Tyrell, AKA the Queen of Thorns.

Olenna

Fans have always loved her sarcastic way [where 😂 comes in], but her wisdom is what got her trending on Twitter post-episode 2. As expected, with her line “You’re a dragon. Be a dragon.”, we see two dragon emojis in the top 15 ranking, among other emojis echoing the YAS Queen theme. 🙌👏

And how could we forget this painful moment?!

bye-fam

Theon Greyjoy is reminded of his days as Reek and doesn’t bother trying to save his sister. How did the twitterverse react? It’s complicated.

Theon

While many made fun of what happened [😂✌️], others were angry, throwing shade, and ready to hate Theon once again [😡😒😤😑😠].

Quite a few sympathized with Theon, given his horrific past of psychological and physical torture [😭😩😢😔]. You don’t just get over that, and it doesn’t help to be in an environment that triggers that experience.

With that in mind, the reactions in emojis to both episodes were quite different.

DragonstoneVStormborn2

While Dragonstone [episode 1] primarily set the stage for the season, with a few moments that got us excited for what’s to come, Stormborn [episode 2] had a handful of tear jerking moments. This is clear in the comparison chart above, which shows more positive face emojis associated with Dragonstone than with Stormborn.

Only 2 episodes in, we’ve seen diverse reactions to many moments in the show. Knowing the unpredictability of Game of Thrones, though, these emotions are going to expand and amplify real quick. 😰

Best of luck GoT fam! If you’d like me to explore reactions to a particular GoT moment later this winter [❄️😏], tweet at @anahitabahri! 👀

 

By Anahita Bahri

Anahita Bahri is an MS in Statistical Practice student at Boston University and Data Scientist Intern at Spotify. In addition to Game of Thrones, Anahita has a passion for music [❤️R&B], data science, journalism, design, steak frites, football ⚽, and, of course, emojis! 😻

 

La Nación, one of the leading newspapers of Argentina, recently published an in-depth interview with PRISMOJI founder Hamdan Azhar on how emojis reveal cultural differences. Read the full interview in Spanish to learn more about the origin of the name PRISMOJI, how emoji data science helps us understand popular sentiment, and more! Also, see below for an English version 🙂

“Emojis are like a prism. A prism takes light in one end and transforms it into its constituent colors. Emojis take raw human emotions on the one end and express them using a few hundred colorful symbols. Emojis are a universal prism because they’re used in nearly every language and can be used to express nearly every emotion: sadness, despair, hope, longing, fear, love, and more.”

Full Interview, in English

How can you describe your job about emojis?

 

I use emojis to understand how people feel about important world events. Emojis are like a prism. A prism takes light in one end and transforms it into its constituent colors. Emojis take raw human emotions on the one end and express them using a few hundred colorful symbols.

 

Emojis are a universal prism because they’re used in nearly every language and can be used to express nearly every emotion: sadness, despair, hope, longing, fear, love, and more. When a major world event occurs – whether involving politics, sports, culture, etc. – I look at the emojis people use when talking about the event to understand how they feel. I also do the opposite: I look at the words people use with emojis to understand what the emojis mean. It’s an endless cycle of emojis.

 

In which way can you apply your previous work experience at PRISMOJI?

 

As a data scientist, my specialty is finding patterns in and telling stories about large amounts of data. I’ve done this in the fields of neuroscience, political campaigns, demography, advertising, decision making, and more. Emojis on social media represent the ultimate form of unstructured data: for example, a tweet might have text, emojis, links, and images. On Election Day in the US, I collected over 2 million tweets. This is chaos, this is noise, this is very hard to interpret. But then we write some code and we visualize the emojis people use on Election Day, over time, and when mentioning Trump and Clinton, and suddenly there’s signal in the noise, we see patterns, we have the aha moment. This is the promise of emoji data science.

 

In relation to your last analysis about emojis, which results did surprise you the most?

 

I was surprised by how much commonality there was across the nine different languages in emojis they used about Ramadan. Across tens of thousands of people around the world, with over 1,800 emojis to choose from, people converge on three emojis most often: the red heart, the crescent moon, and the praying hands. This is cool!

 

We also see that Urdu and Arabic almost never use the praying hands emoji, while most other languages use it very often. This is a powerful example of emojis reflecting deeply held cultural beliefs and practices. In South Asia and the Arab world, praying with folded hands is seen as a Christian and Hindu practice. Muslims pray with our hands held open, turned towards our faces. So this emoji doesn’t show up in Urdu or Arabic tweets. In the West though, Muslims are a minority among a largely Christian population, so even though we still don’t pray with folded hands, using a folded hands emoji seems less foreign to us. More research is obviously needed, but if this holds up, this is a powerful sociolinguistic finding.

 

In your opinion, why do you think that more and more people use and ask for new emojis?

 

Emojis are universal. I can use them with my friends who speak Spanish, Chinese, Arabic and more. Emotions are tricky to convey in words and emojis make it easier. They’re also nuanced which is exciting because we can let them mean whatever we want.

 

How journalists can use emojis in their articles or TV shows?

 

Journalists can use emoji data science as a form of sentiment analysis to understand how peope are reacting to major world events. They add a valuable data point to opinion surveys and anecdotes drawn from journalists own news feeds.

 

What is your favorite emoji? And which one that still doesn’t exist, do you like to ask for it to Unicode?

 

💁🏽, information desk girl, is still my favorite because her name seems ripped from the pages of a Haruki Murakami novel.

Slide01

Emojis have been called the world’s fastest growing language. Yet remarkably little research has been done on differences in emoji usage between cultures. Previous analysis has usually focused on aggregate differences between countries based on data from third party keyboard apps. Here, we analyze emojis in nearly 35,000 tweets in nine languages about a common topic: the Islamic holy month of Ramadan, which began this past weekend. In doing so, we see broad commonalities across languages but also noteworthy and meaningful differences.

We used the Twitter Search API to collect tweets mentioning #Ramadan or رمضان# from May 27-28, 2017, the first two days of Ramadan. Since Twitter automatically detects tweet language and allows for tweet search by language, we were able to obtain tweets from around the world in nine languages: English, Arabic, Urdu, Farsi, Indonesian, Turkish, French, German, and Spanish.

A universal language for a 🌍 celebration, with local variation as well

Previous research has found that the majority of emoji usage, in general, consists of faces and hearts. Our Ramadan dataset largely replicates this pattern. We also observe some interesting and novel findings when we look at the top 10 most commonly used emojis in each language (presented in descending order in the above graphic):

  • In four languages – English, Turkish, German, and Spanish – the ❤️ (red heart) is the most commonly used emoji. In four other languages, the red heart takes second place. (Farsi is the only language in which the red heart not first or second and shows up in fifth place.) The other most frequently occurring heart emojis are 😍 (heart eyes), which is in the top 10 for six languages, 💕 (two hearts), 💙 (blue heart), and 💚 (green heart).
  • 🌙 (crescent moon) is the most common emoji in Arabic, Urdu, and Farsi tweets, and is in second place for English and Turkish tweets, and is used in addition to the crescent moon Twitter automatically appends to the #Ramadan hashtag.
  •  🙏 (praying hands) is the top emoji in Indonesian and French, and is in the top three for English, Farsi, Turkish, German, and Spanish. Among Arabic and Urdu speaking Twitter users, 🙏  is rarely used (perhaps due to associations with non-Muslim prayer in these communities which makes Muslims reluctant to use it in the context of Ramadan).
  •  😭 (loudly crying face) appears in the top 10 emojis in tweets in English, French, and German, and is often used for lowkey complaining about the difficulties of fasting and evening prayers.
  • 💪 (flexed biceps) appears in the top 10 emojis in French and German tweets, usually in motivational tweets encouraging those observing Ramadan to remain strong and go hard (e.g. “Kraft an alle die grad Fasten ❤ Es ist schwer aber wir schaffen das 💪🏼 #Ramadan”, which roughly translates as “Strength to all those who are fasting, it’s hard but we can do this”, or “Très bon #Ramadan à tous les musulmans qui verront ce tweet, courage 💪🏻🔥”, which roughly translates as “A very good Ramadan to all Muslims who see this tweet, courage”)

The long tail of emoji usage

Slide02-ENGLISH

Slide03-ARABIC

One of the fascinating aspects of emoji data science is the degree to which a small set of emojis dominate emoji usage. We see this in our Ramadan dataset as well, where above, we plot the frequency of the top 20 emojis, separately for English and Arabic language tweets. We see the long tail at work, where in English language tweets, frequency falls steeply after the top three emojis (❤️, 🌙, & 🙏), while in Arabic, the top emoji (🌙) is used more than twice as often as the second most common emoji (❤️), after which usage for the remaining emojis level off.

We found that on average, across the nine languages in our analysis, for any given language, the top eight emojis are sufficient to account for 50% of all unique emojis used in the dataset. Even more strikingly, the top 32 emojis, on average, are sufficient to account for 80% of all unique emojis used in the dataset.

Here are the top 20 emojis for the remaining languages in our dataset:

Crescents versus Praying Hands

We can also compare the top 20 emojis used in English vs. Arabic tweets. We see that in both languages, hearts are the most frequently appearing emojis, comprising seven of the top 20 for both English and Arabic. However, the top 20 emojis in English include six faces and five hand gestures, while Arabic only has two faces and three hand gestures. Instead, Arabic includes five plant and flower emojis, which might indicate greater closeness to nature and less emphasis on face emojis used to represent one’s own feelings.

Is there a more robust way of comparing emoji usage between two mutually exclusive subsets of the Ramadan dataset? There is, indeed. Just as in our previous work, where we compared emoji usage in tweets mentioning Kanye West vs. Taylor Swift and Donald Trump vs. Hillary Clinton, we can compute odds ratios for each emoji between two different sets of languages and represent the results in a two dimensional ✈️.

PPT4_Western_VS_Eastern_Censored

In the above plot, for simplicity, we take the naive approach of grouping Western languages on the one hand – English, French, German, and Spanish – and non-Western languages on the other hand – Arabic, Farsi, Indonesian, Turkish, and Urdu. (Since the greatest sample of tweets is from English and Arabic, they exert a disproportionate amount of influence on the final plot.)

We find a strong bifurcation with 🙏 over indexing in Western languages on the right and 🌙 over indexing on non-Western languages on the left, with ❤️  smack in the center. We also see hearts and flowers disproportionately used in Ramadan tweets in non-Western languages. The emojis that lean towards Western languages – 💪, 🔥 (fire), 💯 (hundred points), and 😭 – might all be more common in American and European vernacular usage.

PPT5_prayinghands_vs_crescentmoon_bylanguage.png

Finally, we have one more way of comparing frequency of 🙏 and 🌙 across languages. Above, we see a pattern slightly more nuanced than the division of languages into Western and non-Western. French has the highest usage of 🙏, but it’s closely followed by Indonesian and Turkish. Meanwhile, Arabic and Farsi have minimal usage of 🙏 and Urdu has literally no usage of 🙏 at all in our admittedly modest sample of tweets about Ramadan. We also see 🌙 most heavily used in Arabic tweets, followed by Turkish tweets.

But does 🙏 here really mean praying hands?

The meaning of 🙏 remains highly contentious in certain parts of the internet, with vocal factions continuing to maintain that it actually means “please” or “thank you” and has only minimal religious connotations. A source no less authoritative than Emojipedia maintains to this day that the emoji represents “two hands placed firmly together, meaning please or thank you in Japanese culture.”

Regardless of how the emoji was originally intended to be used, in the context of tweets about Ramadan, 🙏 almost always refers to prayer or more abstractly to Islamic religious or spiritual practices.

Here are some illustrative examples from English language tweets in our dataset:

We also find tweets in Arabic with explicit Islamic prayers appended with 🙏, for example:

What about French, the language that uses 🙏 the most? We observe the same type of usage:

Final thoughts

The late Portuguese writer and Nobel laureate Jose Saramago has a piercing quote about the power of language in one of his books. While The Double was written in 2002, and hence predates emojis, Saramago’s insightful words seem deeply prescient in the modern age:

We have an odd relationship with words. We learn a few when we are small, throughout our lives we collect others through education, conversation, our contact with books, and yet, in comparison, there are only a tiny number about whose meaning, sense, and denotation we would have absolutely no doubts if, one day, we were to ask ourselves seriously what they meant. Thus we affirm and deny, thus we convince and are convinced, thus we argue, deduce, and conclude, wandering fearlessly over the surface of concepts about which we have only the vaguest of ideas, and, despite the false air of confidence that we generally affect as we feel our way along the road in the verbal darkness, we manage, more or less, to understand each other and even, sometimes, to find each other.

In comparison to words, emojis are on the one hand, more universal, yet on the other hand, infinitely more nuanced. Since we use them mostly in interpersonal communications (either when texting friends or while posting on social media), the prevalence of filter bubbles means we may never know what an emoji objectively means in the broader world outside of our personal social networks.

Unlike words, which we learn in university and from books and authoritative sources such as newspapers, we learn emojis in the real world. The risk of meaning being lost in translation is much greater but the intimacy is also greater as well since we ourselves give meaning to, and find meaning in, emojis.

Our analysis of tweets from the opening weekend of Ramadan in nine languages shows us that order can emerge from chaos when it comes to emoji usage. There is tremendous commonality in the emojis we use to talk about Ramadan, whether in Arabic, Urdu, Spanish, English, French, or the four other languages we evaluated.

Nevertheless, meaningful differences also emerge in emoji usage and better understanding these differences may be a major 🔑 that allows us to make sense of the effect of technology on communication, the evolution of language over time, and eventually, each other.

By Hamdan Azhar

 

* A NOTE ON METHODOLOGY: The above analysis relies on an older emoji unicode dictionary that doesn’t include some of the latest emojis that may also be found in Ramadan related tweets, namely 🕋 (kaaba), 🕌  (mosque), or 📿 (prayer beads). For more information on our general methodology, check out our recently released tutorial on Emoji Data Science in R. You can also watch my talk on PRISMOJI and emoji data science at CSV Conference in Portland last month here. If you’d like to contribute to open source emoji data science research, say hi at hello@prismoji.com 🙂

Over the past week, our Emojipedia article “The Resistance Will Be Emojified”, has gone viral on three continents. Yesterday, Mashable dedicated their entire Snapchat story to covering the analysis:
We were also covered in the Huffington Post, Mashable, Bustle, as well as in France and Argentina. Here’s a brief selection of some of our favorite clips!
screen-shot-2017-02-11-at-6-14-39-pm-png
 “We’ve long used emojis to communicate our feelings when words can’t. But what happens when they take on a deeper meaning, becoming a symbol for an entire movement?”
screen-shot-2017-02-11-at-6-14-52-pm-png
“These days, when emotions run high, so does emoji usage…it looks like we’ll continue to see many more ✊  in resistance-related tweets to come.”
screen-shot-2017-02-11-at-6-14-16-pm-png

“Emoji have found a place in pop culture and our hearts, adding the perfect touch to many of our conversations via smartphone and computer. They also, however, became instrumental in the most recent presidential election — so much so that one man decided to analyze how emoji are used to oppose Trump’s policies on Twitter specifically. And the results? Well, to put it simply, they’re fascinating.”

Télam (Argentina)

screen-shot-2017-02-11-at-6-23-28-pm
“Los emojis funcionan como un prisma que convierte una extensa y cambiante masa de discurso público en simpáticos objetos digitales que podemos compartir con otros. Aquí, las redes sociales actúan como la fuerza que le da sentido a los emojis y viceversa.”
screen-shot-2017-02-11-at-6-15-06-pm-png
screen-shot-2017-02-11-at-6-15-13-pm-png

Over the past few months, PRISMOJI has diligently blazed new trails in the emerging field of emoji data science. Today, in a commitment to open data science and open data journalism, we’re proud to present our first tutorial on emoji data science in R. This tutorial is meant to complement our latest article on Emojipedia: “The resistance will be emojified ✊🏽.” (You can find raw code and data to accompany this tutorial in the accompanying Github repository here.)

In this tutorial, we’ll cover:


Part 1 💻: Downloading Twitter data using R

Downloading Twitter data using R has been fairly well documented. Here, we’ll access the Twitter Search API using the twitteR package. First, log into your twitter account, then head to https://apps.twitter.com/, click “Create New App”, fill in the details, and click “Create your Twitter application.” Now click “Keys and Access Tokens”, and click “Create my access token.”

The resulting screen should provide you four strings that you’ll need to access Twitter data: “Consumer Key (API Key)”, “Consumer Secret (API Secret)”, “Access Token”, and “Access Token Secret.” These are all uniquely associated with your Twitter account and you should not share these with anyone else. Now, we can download Twitter data using just a few lines of code.

This code snippet will get you authenticated with Twitter (just replace XXX with the value of each string from above):

library(twitteR)
library(reshape)
api_key <- 'XXX'
api_secret <- 'XXX'
access_token <- 'XXX'
access_token_secret <- 'XXX'
setup_twitter_oauth(api_key, api_secret, access_token, access_token_secret)

Now, we’re ready to pull tweets. We use the searchTwitter function which requires us to specify a search term; here, we’ll use #nobannowall. Bogdan Rau has a good overview of other types of valid search terms, but in general, anything that works at twitter.com/search should work here. The n parameter is important. Generally, we’ve found that you can request n=100,000 tweets which will usually lead to rate-limiting but will still give you results within about 30-60 minutes. (For sparse hashtags, it will return fewer tweets.)

In terms of date range, the Search API in general only goes back 7-10 days at most, and is often delayed by a day or so for current tweets, so keep this in mind. An important note: for a highly popular hashtag, the Search API does not return a representative distribution of tweets (i.e. if you request tweets from Feb. 1 – Feb 5, it’s likely you’ll only get tweets from Feb. 5). One workaround is to pull tweets from different days separately. Also, we remove retweets because this helps us get cleaner emoji data but you can toggle this parameter. df here returns a dataset with many variables, most of which are unnecessary for our work; you can choose to retain them if you wish.

Here’s the code:

set.seed(20170202); ht <- '#nobannowall'; 
tweets.raw <- searchTwitter(ht, n = 1000, lang = 'en', since = '2017-01-29', until = '2017-01-29');
df <- twListToDF(strip_retweets(tweets.raw, strip_manual = TRUE, strip_mt = TRUE)); df$hashtag <- ht; df$created <- as.POSIXlt(df$created); df$text <- iconv(df$text, 'latin1', 'ASCII', 'byte'); df$url <- paste0('https://twitter.com/', df$screenName, '/status/', df$id); df <- rename(df, c(retweetCount = 'retweets'));
df.a <- subset(df, select = c(text, created, url, latitude, longitude, retweets, hashtag));
nrow(df.a); head(df.a);
setwd('.../PRISMOJI/tutorial'); write.csv(df.a, paste0('tweets.cleaned_', format(min(df.a$created), '%m%d'), '-', format(max(df.a$created), '%m%d'), '_', ht, '_', Sys.Date(), '_', format(Sys.time(), '%H-%M-%S'), '_n', nrow(df.a), '.csv'), row.names = FALSE);
tweets <- df; tweets$z <- 1; tweets$created <- as.POSIXlt(tweets$created); nrow(tweets); min(tweets$created); max(tweets$created); median(tweets$created);

Curious what the output looks like? Here’s a screenshot:

screen-shot-2017-02-06-at-2-48-46-am-png

Part 2 ✍🏼: Using Unicode pattern matching to extract emojis from tweets

Using the methodology described in Part 1, we read in tweets, separately for Jan. 28 and Jan. 29, for five different hashtags: #NoBanNoWall, #NoMuslimBan, #NotMyPresident, #TheResistance, and #WomensMarch. (Here is a good resource for hashtag brainstorming which will give you a network of related hashtags for a given seed hashtag.)

Within each of the five resulting datasets, we deduplicated tweets by both URL and user name. (For example, there are often Twitter bot accounts that tweet multiple times, using identical text and/or emojis, which can distort results.) We then combined these into one dataset which you can find on Github called “tutorial_tweets_raw.csv.”

We then download two emoji dictionaries – one provided by Lauren Ancona and Chris Tufts whose earlier work on emojis in Philadelphia was an invaluable starting point in our own work, and the other by Jessica Peterka-Bonetta who built a powerful emoji decoder specifically for R. We combine these dictionaries into a new dataset called emojis.

⁎ As a caveat, both of these dictionaries contain only 842 emojis and are slightly out of date with the latest and greatest emojis. Updating these to be current would be really cool! Please drop us a line if you get a chance to work on this 🙂

[UPDATE (10/5/2017): The linguist Kate Lyons of the University of Illinois – who has done great work producing emoji maps of San Francisco – has created an updated emoji dictionary covering 2,204 emojis, including skin tone emojis! This is a tremendous contribution to emoji research and we look forward to using her dictionary going forward.]

Using our new emoji dictionary – which has a column named rencoding to represent
how R represents each emoji – we compare our dataset of 57,522 tweets with our dataset of 842 emojis and create a full matrix (57,522 x 842) to assess the presence of each emoji in each tweet. This is the most time-consuming part but using sapply and vectorization, it runs in less than 3 minutes here. We save the resultant matrix as tweets.emojis.matrix and then run colSums across each column to compute an initial emoji count.

Here’s the code:

tweets <- tweets.final;
# tweets <- subset(tweets.final, hashtag %in% c('#womensmarch'));
## create full tweets by emojis matrix
df.s <- matrix(NA, nrow = nrow(tweets), ncol = ncol(emojis)); 
system.time(df.s <- sapply(emojis$rencoding, regexpr, tweets$text, ignore.case = T, useBytes = T));
rownames(df.s) <- 1:nrow(df.s); colnames(df.s) <- 1:ncol(df.s); df.t <- data.frame(df.s); df.t$tweetid <- tweets$tweetid;
# merge in hashtag data from original tweets dataset
df.a <- subset(tweets, select = c(tweetid, hashtag)); 
df.u <- merge(df.t, df.a, by = 'tweetid'); df.u$z <- 1; df.u <- arrange(df.u, tweetid); 
tweets.emojis.matrix <- df.u;
## create emoji count dataset
df <- subset(tweets.emojis.matrix)[, c(2:843)]; count  -1);
emojis.m <- cbind(count, emojis); emojis.m <- arrange(emojis.m, desc(count));
emojis.count  1); emojis.count$dens <- round(1000 * (emojis.count$count / nrow(tweets)), 1); emojis.count$dens.sm <- (emojis.count$count + 1) / (nrow(tweets) + 1);
emojis.count$rank <- as.numeric(row.names(emojis.count));
emojis.count.p <- subset(emojis.count, select = c(name, dens, count, rank));
# print summary stats
subset(emojis.count.p, rank <= 10);
num.tweets <- nrow(tweets); df.t  -1); num.tweets.with.emojis  0]); num.emojis <- sum(emojis.count$count);
min(tweets$created); max(tweets$created); median(tweets$created);
num.tweets; num.tweets.with.emojis; round(100 * (num.tweets.with.emojis / num.tweets), 1); num.emojis; nrow(emojis.count);

Here’s what the output looks like:

screen-shot-2017-02-06-at-3-33-08-am

Pretty cool! 😎

Part 3 📊: Visualizing emojis

The table above is nice to look at it, but is there a prettier way we can visualize the data in emojis.count? A simple approach is to make a bar chart of top emojis where we insert the appropriate emoji image on top of each of the bars using the annotation_custom function in ggplot. (If you’re trying to replicate this in other languages, i.e. Python, try searching for custom plot annotations.) In order to do this, we first read in all 842 emoji images using grid::rasterGrob.

Here’s what the code looks like:

df.plot <- subset(emojis.count.p, rank <= 10); xlab <- 'Rank'; ylab <- 'Overall Frequency (per 1,000 Tweets)';
setwd('.../PRISMOJI/tutorial/ios_9_3_emoji_files'); df.plot <- arrange(df.plot, name);
imgs <- lapply(paste0(df.plot$name, '.png'), png::readPNG); g <- lapply(imgs, grid::rasterGrob);
k <- 0.20 * (10/nrow(df.plot)) * max(df.plot$dens); df.plot$xsize <- k; df.plot$ysize <- k; df.plot$ysize <- k * (df.plot$dens / max(df.plot$dens));
df.plot <- arrange(df.plot, name);
g1 <- ggplot(data = df.plot, aes(x = rank, y = dens)) +
  geom_bar(stat = 'identity', fill = 'dodgerblue4') +
  xlab(xlab) + ylab(ylab) +
  mapply(function(x, y, i) {
    annotation_custom(g[[i]], xmin = x-0.5*df.plot$xsize[i], xmax = x+0.5*df.plot$xsize[i], 
                      ymin = y-0.5*df.plot$ysize[i], ymax = y+0.5*df.plot$ysize[i])},
    df.plot$rank, df.plot$dens, seq_len(nrow(df.plot))) +
  scale_x_continuous(expand = c(0, 0), breaks = seq(1, nrow(df.plot), 1), labels = seq(1, nrow(df.plot), 1)) +
  scale_y_continuous(expand = c(0, 0), limits = c(0, 1.10 * max(df.plot$dens))) +
  theme(panel.grid.minor.y = element_blank(),
        axis.title.x = element_text(size = 10), axis.title.y = element_text(size = 14), 
        axis.text.x  = element_text(size = 8, colour = 'black'), axis.text.y  = element_text(size = 8, colour = 'black'));
g1;
setwd('.../PRISMOJI/tutorial')
png(paste0('emoji_barchart_', as.Date(min(tweets$created)), '_', as.Date(max(tweets$created)), '_', Sys.Date(), '_', format(Sys.time(), '%H-%M-%S'), '_n', nrow(tweets), '.png'), 
    width = 6600, height = 4000, units = 'px', res = 1000);
g1; dev.off();

The output looks like this:

emoji_barchart_2017-01-28_2017-01-29_2017-02-06_05-11-13_n57552

⁎ We can tweak the tweets assignment in Part 2 above, right before we run create tweets.emojis.matrix, to replicate the above analysis for a given subset of the dataset instead of running it on all tweets.

Part 4 🤓: Visualizing emojis (Advanced)

The next step after visualizing the top emojis in the overall dataset is to compare emoji frequency between two different subsets of the data. In order to do this efficiently, we first create a reduced representation of the tweets.emojis.matrix that has the original tweet appended with a string of all the unique emojis in that tweet.

This code is fairly straightforward:

df.s <- data.frame(matrix(NA, nrow = nrow(tweets), ncol = 2)); names(df.s) <- c('tweetid', 'emoji.ids'); df.s$tweetid <- 1:nrow(tweets);
system.time(df.s$emoji.ids  -1), sep = '', collapse = ', '))); 
system.time(df.s$num.emojis <- sapply(df.s$emoji.ids, function(x) length(unlist(strsplit(x, ', '))))); 
df.s.emojis  0);
df.s.nonemojis <- subset(df.s, num.emojis == 0); df.s.nonemojis$emoji.names <- '';
# convert to long, only for nonzero entries
df.l <- cSplit(df.s.emojis, splitCols = 'emoji.ids', sep = ', ', direction = 'long')
map <- subset(emojis, select = c(emojiid, name)); map$emojiid <- as.numeric(map$emojiid);
df.m <- merge(df.l, map, by.x = 'emoji.ids', by.y = 'emojiid'); df.m <- arrange(df.m, tweetid); df.m <- rename(df.m, c(name = 'emoji.name'));
tweets.emojis.long <- subset(df.m, select = c(tweetid, emoji.name));
df.n <- aggregate(emoji.name ~ tweetid, paste, collapse = ', ', data = df.m);
## merge back with original tweets dataset
df.f <- merge(df.s.emojis, df.n, by = 'tweetid'); df.f <- rename(df.f, c(emoji.name = 'emoji.names'));
df.g <- rbind(df.f, df.s.nonemojis); df.g <- arrange(df.g, tweetid);
df.h <- merge(tweets, df.g, by = 'tweetid', all.x = TRUE); df.h$emoji.ids <- NULL; df.h$tweetid <- as.numeric(df.h$tweetid); df.h <- arrange(df.h, tweetid);
tweets.emojis <- df.h;

Now, we define two different subsets of the data, then count the emojis in those subsets based on tweets.emojis. For example, let’s compare emoji usage between tweets mentioning #womensmarch and tweets mentioning #theresistance. First, we create the two subsets, count emojis in each subset, and create a combined dataset to facilitate comparisons:

df.1 <- subset(tweets.emojis, grepl(paste(c('#womensmarch'), collapse = '|'), tolower(tweets.emojis$text)));
df.2 <- subset(tweets.emojis, grepl(paste(c('#theresistance'), collapse = '|'), tolower(tweets.emojis$text)));
nrow(df.1); nrow(df.2);
# dataset 1
df.a <- subset(subset(df.1, emoji.names != ''), select = c(tweetid, emoji.names)); df.a$emoji.names <- as.character(df.a$emoji.names);
df.b <- data.frame(table(unlist(strsplit(df.a$emoji.names, ',')))); names(df.b) <- c('var', 'freq'); df.b$var <- trimws(df.b$var, 'both'); df.b <- subset(df.b, var != '');
df.c <- aggregate(freq ~ var, data = df.b, function(x) sum(x)); df.c <- df.c[with(df.c, order(-freq)), ]; row.names(df.c) <- NULL;
df.d  1); df.d$dens <- round(1000 * (df.d$freq / nrow(df)), 1); df.d$dens.sm <- (df.d$freq + 1) / (nrow(df) + 1); df.d$rank <- as.numeric(row.names(df.d)); df.d <- rename(df.d, c(var = 'name'));
df.e <- subset(df.d, select = c(name, dens, dens.sm, freq, rank)); 
df.e$ht <- as.character(arrange(data.frame(table(tolower(unlist(str_extract_all(df.1$text, '#\\w+'))))), -Freq)$Var1[1]);
df.e[1:10, ]; emojis.count.1 <- df.e;
# dataset 2
df.a <- subset(subset(df.2, emoji.names != ''), select = c(tweetid, emoji.names)); df.a$emoji.names <- as.character(df.a$emoji.names);
df.b <- data.frame(table(unlist(strsplit(df.a$emoji.names, ',')))); names(df.b) <- c('var', 'freq'); df.b$var <- trimws(df.b$var, 'both'); df.b <- subset(df.b, var != '');
df.c <- aggregate(freq ~ var, data = df.b, function(x) sum(x)); df.c <- df.c[with(df.c, order(-freq)), ]; row.names(df.c) <- NULL;
df.d  1); df.d$dens <- round(1000 * (df.d$freq / nrow(df)), 1); df.d$dens.sm <- (df.d$freq + 1) / (nrow(df) + 1); df.d$rank <- as.numeric(row.names(df.d)); df.d <- rename(df.d, c(var = 'name'));
df.e <- subset(df.d, select = c(name, dens, dens.sm, freq, rank));
df.e$ht <- as.character(arrange(data.frame(table(tolower(unlist(str_extract_all(df.2$text, '#\\w+'))))), -Freq)$Var1[1]);
df.e[1:10, ]; emojis.count.2 <- df.e;
# combine datasets and create final dataset
names(emojis.count.1)[-1] <- paste0(names(emojis.count.1)[-1], '.1'); names(emojis.count.2)[-1]  0 & (df.a$dens.2 > df.a$dens.1), -1 * round(100 * ((df.a$dens.2 / df.a$dens.1) - 1), 0), NA));
df.a$logor <- log(df.a$dens.sm.1 / df.a$dens.sm.2);
df.a$dens.mean  0); nrow(df.b);
df.c <- subset(df.b, select = c(name, dens.1, dens.2, freq.1, freq.2, dens.mean, round(logor, 2)));
df.c <- df.c[with(df.c, order(-logor)), ]; row.names(df.c) <- NULL; nrow(df.c); df.c;
emojis.comp.p <- df.c;

The key parameter here is k, which sets a threshold for how many emojis we want in the final comparison dataset, and df.b more broadly defines that dataset. (Here, the comparison dataset contains emojis that rank in the top 50 in either subset, have a frequency of at least 5 in either dataset, and are greater than zero in both datasets. Another useful parameter option could be to threshold on abs(logor) being greater than 0.5 or 1 which will yield only the most polarized emojis. Regardless, we print nrow(df.b) to give us a sense of how many emojis the thresholding criteria yield.

Here’s a snippet of the first and last 5 observations from the resulting emoji comparison dataset, emojis.comp.p:

screen-shot-2017-02-06-at-5-45-55-am-png

The results are interesting and seem intuitive. Pink hearts and celebratory emojis over-index on #womensmarch while more activist emojis and New York-specific ones overindex on #theresistance. (Emojis more associated with the first dataset we defined, df.1, end up with a positive odds ratio, and vice-versa. Odds ratios close to 0 indicate emojis that are used equally frequently with both hashtags.)

Now, visualizing the two-way spread of emojis across both datasets is trivial given our earlier foundations; namely, we can use custom annotations to plot log odds ratios and overall densities on an x-y plane.

Here’s the code:

setwd('.../PRISMOJI/tutorial/ios_9_3_emoji_files');
df.t <- arrange(emojis.comp.p, name);
imgs <- lapply(paste0(df.t$name, '.png'), png::readPNG)
g <- lapply(imgs, grid::rasterGrob);
## make plot  
df.t <- arrange(emojis.comp.p, logor)
xlab <- paste0('Emoji Valence: Log Odds Ratio (', paste0(unique(emojis.count.2$ht), '  ', unique(emojis.count.1$ht), ')'));
ylab <- 'Overall Frequency (Per 1,000 Tweets)'
k <- 8 # size parameter for median element
xsize <- (k/100) * (max(df.t$logor) - min(df.t$logor)); ysize <- (k/100) * (max(df.t$dens.mean) - min(df.t$dens.mean));
df.t$xsize <- xsize; df.t$ysize <- ysize;
df.t$dens.m  median(df.t$dens.mean), round(sqrt((df.t$dens.mean / min(df.t$dens.mean))), 2), 1);
df.t$xsize <- df.t$dens.m * df.t$xsize; df.t$ysize <- df.t$dens.m * df.t$ysize;
df.t <- arrange(df.t, name);
g1 <- ggplot(df.t, aes(jitter(logor), dens.mean)) +
  xlab(xlab) + ylab(ylab) +
  mapply(function(x, y, i) {
    annotation_custom(g[[i]], xmin = x-0.5*df.t$xsize[i], xmax = x+0.5*df.t$xsize[i], 
                      ymin = y-0.5*df.t$ysize[i], ymax = y+0.5*df.t$ysize[i])},
    jitter(df.t$logor), df.t$dens.mean, seq_len(nrow(df.t))) +
  scale_x_continuous(limits = c(1.15 * min(df.t$logor), 1.15 * max(df.t$logor))) +
  scale_y_continuous(limits = c(0, 1.20 * max(df.t$dens.mean))) +
  geom_vline(xintercept = 0) + geom_hline(yintercept = 0) +
  theme_bw() +
  theme(axis.title.x = element_text(size = 10), axis.title.y = element_text(size = 10), 
        axis.text.x  = element_text(size = 8, colour = 'black'), axis.text.y  = element_text(size = 8, colour = 'black'));
setwd('.../PRISMOJI/tutorial');
png(paste0('emojis.comp.p_', Sys.Date(), '_', format(Sys.time(), '%H-%M-%S'), '.png'), 
    width = 6600, height = 4000, units = 'px', res = 1000);
g1; dev.off();

And here’s the output:
emojis-comp-p_2017-02-06_05-36-24

Part 5 🚀: Next Steps

In our next tutorial, we’ll dig a little deeper into text analysis of datasets with emojis. Meanwhile, given this foundation of emoji data science, there are a few next steps we can imagine:

  • emoji network visualizations to understand emoji-emoji cooccurrence (i.e. Mailchimp published a great analysis in 2015)
  • interactive emoji dashboards (i.e. we’re big fans of the University of Virginia’s Twitter Visualization Project and their time series plot of emoji usage during the presidential debates.)
  • updating the above protocol to include the latest batch of 1,851 emoji characters in Unicode 9.0
  • using machine learning and natural language processing to better leverage the text data in tweets to understand what emojis mean
  • replicating the above protocol for Instagram and other social media platforms

If you’re interested in working with us on any of the above – or have your own ideas – email us at hello@prismoji.com! We’re happy to chat with prospective interns, especially people with data science or engineering backgrounds who are natural storytellers and can see the forest from the trees.

By Hamdan Azhar

Last week, election results from all states were finally certified. While most headlines focused on Hillary Clinton’s 2.8 million popular votes lead over Donald Trump, the results also debunked claims that had been circulating over the past few weeks.

Visualization by Hamdan Azhar

Contrary to early reports, Trump ended up receiving two million more votes than Mitt Romney did in 2012. Meanwhile, Clinton fell short of Obama’s 2012 popular vote totals by about 70,000. Third party candidates surged from 2.2 million votes in 2012 to just over 7.8 million in 2016.

Visualization by Hamdan Azhar

Final results also reveal that despite early claims of historically low turnout, the number of raw votes cast in the 2016 presidential election – 136,628,459 – is actually the highest total ever. (The previous highest was the 2008 election in which 131.1 million votes were cast.)

Even while adjusting for the voting eligible population, Professor Michael McDonald of the University of Florida estimates this election had a voter turnout rate of 58.9%. While this is lower than the 61.6% turnout in 2008 (which had the highest turnout since 1968), it’s still significantly higher than the 56% estimated by pundits immediately after the election.

Check out our complete analysis in Forbes!

peach-emoji-usage-twitter-emojipedia-1

Apple recently came under fire for proposing a change to the 🍑 peach emoji that made it look more fruit-like and less butt-like. “What’s happening to emojis represents the worst kind of gentrification of the internet,” charged Buzzfeed. Mashable was even more dramatic, exclaiming: “Apple just ruined texting.”

While Apple soon retreated, the episode demonstrated the strength of people’s feelings about emojis and highlighted how much of their meaning remains personal and subjective. We were curious what the data said on the question of fruit vs. butt so we turned to Twitter. Check out PRISMOJI’s complete analysis at Emojipedia!

slide3

The past week has seen a whirlwind of social media activity around the death of Fidel Castro, Thanksgiving, and Black Friday. We were curious about how people used emojis to discuss these topics so we looked at some data from Twitter. Check out the complete post on Emojipedia!