DataScience+ We share R tutorials from scientists at academic and scientific institutions with a goal to give everyone in the world access to a free knowledge. Our tutorials cover different topics including statistics, data manipulation and visualization!
Visualizing Data

How to create a Twitter Sentiment Analysis using R and Shiny

Everytime you release a product or service you want to receive feedback from users so you know what they like and what they don’t. Sentiment Analysis can help you. I will show you how to create a simple application in R and Shiny to perform Twitter Sentiment Analysis in real-time. I use RStudio.

We will be able to see if they liked our products or not. Also, we will create a wordcloud to find out why they liked it and why not.

First, I will create a Shiny Project. To learn how to create a Shiny apps you might read this tutorial by Teja Kodali and another tutorial by Aaron Gowins.

Then, in the ui.R file, I put this code:

titlePanel("Sentiment Analysis"), #Title
textOutput("currentTime"),   #Here, I show a real time clock
h4("Tweets:"),   #Sidebar title
dataTableOutput('tweets_table') #Here I show the users and the sentiment

Show a plot of the generated distribution:

plotOutput("distPlot"), #Here I will show the bars graph
plotOutput("positive_wordcloud") #Cloud for positive words
plotOutput("negative_wordcloud") #Cloud for negative words
plotOutput("neutral_wordcloud") #Cloud for neutral words

Here, I will show a title, the current time, a table with Twitter user name, a bar graph and wordclouds. Also you have to put your consumer key and secret (replace xxxxxxxxxx). You will have to create and application in Twitter Developers site and then extract this info.

Now, I will create the server side:

shinyServer(function(input, output, session) {
  setup_twitter_oauth(consumer_key = "xxxxxxxxxx", consumer_secret = "xxxxxxxxxxxx")
  token <- get("oauth_token", twitteR:::oauth_cache)
  output$currentTime <- renderText({invalidateLater(1000, session)
                                  paste("Current time is: ",Sys.time())})
    count_positive = 0
    count_negative = 0
    count_neutral = 0
    positive_text <- vector()
    negative_text <- vector()
    neutral_text <- vector()
    vector_users <- vector()
    vector_sentiments <- vector()
    tweets_result = ""
    tweets_result = searchTwitter("word-to-find-in-twitter")
    for (tweet in tweets_result){
      print(paste(tweet$screenName, ":", tweet$text))
       vector_users <- c(vector_users, as.character(tweet$screenName));
       if (grepl("lindo", tweet$text, = TRUE) == TRUE | grepl("Wonderful", tweet$text, = TRUE) | grepl("Awesome", tweet$text, = TRUE)){
        count_positive = count_positive + 1
         vector_sentiments <- c(vector_sentiments, "Positive")
        positive_text <- c(positive_text, as.character(tweet$text))
       } else if (grepl("Boring", tweet$text, = TRUE) | grepl("I'm sleeping", tweet$text, = TRUE)) { 
        count_negative = count_negative + 1
        vector_sentiments <- c(vector_sentiments, "Negative")
        negative_text <- c(negative_text, as.character(tweet$text))
       } else {
        count_neutral = count_neutral + 1
        vector_sentiments <- c(vector_sentiments, "Neutral")
        neutral_text <- c(neutral_text, as.character(neutral_text))
    df_users_sentiment <- data.frame(vector_users, vector_sentiments)
    output$tweets_table = renderDataTable({

    output$distPlot <- renderPlot({
      results = data.frame(tweets = c("Positive", "Negative", "Neutral"), numbers = c(count_positive,count_negative,count_neutral))
      barplot(results$numbers, names = results$tweets, xlab = "Sentiment", ylab = "Counts", col = c("Green","Red","Blue"))
      if (length(positive_text) > 0){
        output$positive_wordcloud <- renderPlot({ wordcloud(paste(positive_text, collapse=" "), min.freq = 0, random.color=TRUE, max.words=100 ,colors=brewer.pal(8, "Dark2"))  })
      if (length(negative_text) > 0) {
        output$negative_wordcloud <- renderPlot({ wordcloud(paste(negative_text, collapse=" "), random.color=TRUE,  min.freq = 0, max.words=100 ,colors=brewer.pal(8,"Set3"))  })
      if (length(neutral_text) > 0){
        output$neutral_wordcloud <- renderPlot({ wordcloud(paste(neutral_text, collapse=" "), min.freq = 0, random.color=TRUE , max.words=100 ,colors=brewer.pal(8, "Dark2"))  })

Here a screenshot of the shiny app we created:

It's a really simply code, not complex at all. The purpose of it is just for testing and so you guys can practice R language. If you have questions just let me know.