iPhone X vs. Pixel 2

#Loading necessary libraries:
library(twitteR)
library(tidytext)
library(stringr)
library(ggplot2)
library(dplyr)
library(knitr)
library(pander)
library(scales)
library(wordcloud)
library(reshape2)
setup_twitter_oauth(consumer_key, consumer_secret, access_token, access_secret)
## [1] "Using direct authentication"

Introduction

With the holidays coming up and the excitement over the release of Apple’s new iPhone X earlier this month and the release of Google’s Pixel 2 XL in October. I thought it would be interesting to look at how the twitter community is currently responding to the iPhone X vs. Pixel 2 XL. There has been a lot of hype around which phone is “better” in terms of a variety of factors. Although this MacRumors article does not provide a clear answer for which is better, I believe the twitter community can help us determine which has more favorable feedback.

Metholodogy

In this assignment, we will download the appropriate twitter data, look through the data to find positive and negative responses to the iPhone X and Pixel 2 XL and determine which is more favorable based on the one that shows a higher percentage of positive vs. negative tweets, out of the 1,000 we look at for each product.

*Please note that this data changes daily, and multiple times throughout a day, because it is based on the last 1,000 tweets associated with #iPhoneX and #Pixel2XL. Therefore, in the process of doing this analysis, the results changed slightly.

We begin by loading 1,000 of the most recent tweets on iPhone X and 1,000 of the most recent tweets on Pixel 2 XL.

#Loading 1,000 iPhone X tweets from Twitter
num_tweets <- 1000
iPhoneX <- searchTwitter('#iPhoneX', n = num_tweets)
head(iPhoneX)
## [[1]]
## [1] "uyvnda: RT @baddicandii: Twitter I need 290K retweets on this tweet for brand new #iPhoneX help me please <ed><U+00A0><U+00BD><ed><U+00B9><U+008F> https://t.co/k694Z8KlHW"
## 
## [[2]]
## [1] "LyonLyon6969000: RT @ConcoursWinner: [#ActuDuWinner] Malgrès son prix, sur un test de rapidité l'#iPhoneX se retrouve derrière le Samsung Galaxy Note 8.\n\nLi<U+0085>"
## 
## [[3]]
## [1] "sectest9: RT @evankirstel: #iPhoneX face recognition at work <ed><U+00A0><U+00BD><ed><U+00B8><U+0082>#infosec #security https://t.co/GgXVNDJBuF"
## 
## [[4]]
## [1] "iPoof: Have to geek out here sorry. But #StrangerThings2 looks stunning in #DolbyVision on the #iPhoneX screen"
## 
## [[5]]
## [1] "InfoSecurity99: RT @evankirstel: #iPhoneX face recognition at work <ed><U+00A0><U+00BD><ed><U+00B8><U+0082>#infosec #security https://t.co/GgXVNDJBuF"
## 
## [[6]]
## [1] "_lee_favour: RT @baddicandii: Twitter I need 290K retweets on this tweet for brand new #iPhoneX help me please <ed><U+00A0><U+00BD><ed><U+00B9><U+008F> https://t.co/k694Z8KlHW"
#Loading 1,000 Pixel 2 tweets from Twitter
Pixel2XL <- searchTwitter('#Pixel2XL', n = num_tweets)
head(Pixel2XL)
## [[1]]
## [1] "SuperRichMedia: Sorry to say that the Bluetooth stack on the #Pixel2XL is the most buggy I've ever encountered. Esp with #DayDream<U+0085> https://t.co/TpNwv7oY8S"
## 
## [[2]]
## [1] "JamesCLv2: Took a hike with Lil man. #Pixel2XL @madebygoogle https://t.co/5sFGjuhKQf"
## 
## [[3]]
## [1] "evgeniylutskiy: Portrait by Google Pixel 2 XL. No filters.\n#googlepixel2xl #pixel2xl #portrait #iphone #nyc<U+0085> https://t.co/wiZUwlf3SI"
## 
## [[4]]
## [1] "anshelsag: I think today is the day I actually go out and do some comparisons between the #Note8, #Pixel2XL and #iPhoneX :)"
## 
## [[5]]
## [1] "abusafar6: #Pixel2XL I<U+0092>m impressed <ed><U+00A0><U+00BD><ed><U+00B8><U+008D><ed><U+00A0><U+00BD><ed><U+00B8><U+008D><ed><U+00A0><U+00BD><ed><U+00B8><U+008D>"
## 
## [[6]]
## [1] "ARIANAGRANDE_1Q: Pixel 2 XL Add New Issue Of Unresponsive Screen Edges To List Other Problems\nhttps://t.co/BsFqSRqCTj\n\n#technews #pixel2xl #android"

Then we need to convert the lists of tweets into data frames for both the iPhone X and Pixel 2 XL tweets.

Figure 1: Converting Lists of Tweets into Data Frames for iPhoneX and Pixel 2XL

iPhoneX_df <- twListToDF(iPhoneX)
pander(head(iPhoneX_df))
Table continues below
text favorited favoriteCount
RT @baddicandii: Twitter I need 290K retweets on this tweet for brand new #iPhoneX help me please https://t.co/k694Z8KlHW FALSE 0
RT @ConcoursWinner: [#ActuDuWinner] Malgrès son prix, sur un test de rapidité l’#iPhoneX se retrouve derrière le Samsung Galaxy Note 8. Li FALSE 0
RT @evankirstel: #iPhoneX face recognition at work #infosec #security https://t.co/GgXVNDJBuF FALSE 0
Have to geek out here sorry. But #StrangerThings2 looks stunning in #DolbyVision on the #iPhoneX screen FALSE 0
RT @evankirstel: #iPhoneX face recognition at work #infosec #security https://t.co/GgXVNDJBuF FALSE 0
RT @baddicandii: Twitter I need 290K retweets on this tweet for brand new #iPhoneX help me please https://t.co/k694Z8KlHW FALSE 0
Table continues below
replyToSN created truncated replyToSID id
NA 2017-11-12 21:26:29 FALSE NA 929822732879106049
NA 2017-11-12 21:26:24 FALSE NA 929822713471995905
NA 2017-11-12 21:26:17 FALSE NA 929822681276575750
NA 2017-11-12 21:26:14 FALSE NA 929822670136446976
NA 2017-11-12 21:26:05 FALSE NA 929822630953259009
NA 2017-11-12 21:26:04 FALSE NA 929822627790770181
Table continues below
replyToUID statusSource screenName
NA Twitter for iPhone uyvnda
NA Twitter for Android LyonLyon6969000
NA helloworld-b sectest9
NA Twitter for iPad iPoof
NA ifnotseceurity InfoSecurity99
NA Twitter for Android _lee_favour
retweetCount isRetweet retweeted longitude latitude
6752 TRUE FALSE NA NA
121 TRUE FALSE NA NA
103 TRUE FALSE NA NA
0 FALSE FALSE NA NA
103 TRUE FALSE NA NA
6752 TRUE FALSE NA NA
Pixel2XL_df <- twListToDF(Pixel2XL)
pander(head(Pixel2XL_df))
Table continues below
text
Sorry to say that the Bluetooth stack on the #Pixel2XL is the most buggy I’ve ever encountered. Esp with #DayDream https://t.co/TpNwv7oY8S
Took a hike with Lil man. #Pixel2XL @madebygoogle https://t.co/5sFGjuhKQf
Portrait by Google Pixel 2 XL. No filters. #googlepixel2xl #pixel2xl #portrait #iphone #nyc https://t.co/wiZUwlf3SI
I think today is the day I actually go out and do some comparisons between the #Note8, #Pixel2XL and #iPhoneX :)
#Pixel2XL Im impressed
Pixel 2 XL Add New Issue Of Unresponsive Screen Edges To List Other Problems https://t.co/BsFqSRqCTj #technews #pixel2xl #android
Table continues below
favorited favoriteCount replyToSN created truncated
FALSE 0 NA 2017-11-12 21:25:41 TRUE
FALSE 0 NA 2017-11-12 21:12:10 FALSE
FALSE 0 NA 2017-11-12 20:50:25 FALSE
FALSE 0 NA 2017-11-12 20:35:37 FALSE
FALSE 0 NA 2017-11-12 20:35:12 FALSE
FALSE 0 NA 2017-11-12 20:31:14 FALSE
Table continues below
replyToSID id replyToUID
NA 929822533477527553 NA
NA 929819131431608320 NA
NA 929813656359129089 NA
NA 929809930554523650 NA
NA 929809829228613638 NA
NA 929808828065046528 NA
Table continues below
statusSource screenName
Twitter for Android SuperRichMedia
Twitter for Android JamesCLv2
Instagram evgeniylutskiy
Twitter Web Client anshelsag
Twitter for iPhone abusafar6
TweetDeck ARIANAGRANDE_1Q
retweetCount isRetweet retweeted longitude latitude
0 FALSE FALSE NA NA
0 FALSE FALSE NA NA
0 FALSE FALSE -74.02027778 40.80861111
0 FALSE FALSE NA NA
0 FALSE FALSE NA NA
0 FALSE FALSE NA NA

Source of Tweets

Similarly to the lecture notes in unit 11, we will be looking at the status sources for both the iPhoneX and Pixel 2XL tweets.

Figure 2: Sources for iPhoneX tweets

iPhoneX_df %>% group_by(statusSource) %>% 
  summarize(n = n()) %>% 
  arrange(desc(n)) %>% 
  top_n(5)
## Selecting by n
## # A tibble: 5 x 2
##                                                                  statusSource
##                                                                         <chr>
## 1 "<a href=\"http://twitter.com/download/android\" rel=\"nofollow\">Twitter f
## 2 "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter fo
## 3    "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>"
## 4  "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Twitter Lite</a>"
## 5 "<a href=\"http://twitter.com/#!/download/ipad\" rel=\"nofollow\">Twitter f
## # ... with 1 more variables: n <int>
iPhoneX_df$statusSource = substr(iPhoneX_df$statusSource, 
                            regexpr('>', iPhoneX_df$statusSource) +1,
                            regexpr('</a>', iPhoneX_df$statusSource) -1)
iPhoneX_platform <-iPhoneX_df %>% group_by(statusSource) %>% 
                        summarize(n = n()) %>%
                        mutate(percent_of_tweets = n/sum(n)) %>% 
                        arrange(desc(n))
iPhoneX_platform %>% top_n(5)
## Selecting by percent_of_tweets
## # A tibble: 5 x 3
##          statusSource     n percent_of_tweets
##                 <chr> <int>             <dbl>
## 1 Twitter for Android   325             0.325
## 2  Twitter for iPhone   324             0.324
## 3  Twitter Web Client   111             0.111
## 4        Twitter Lite    33             0.033
## 5    Twitter for iPad    28             0.028

Figure 3: Sources for Pixel 2XL tweets

Pixel2XL_df %>% group_by(statusSource) %>% 
  summarize(n = n()) %>% 
  arrange(desc(n)) %>% 
  top_n(5)
## Selecting by n
## # A tibble: 5 x 2
##                                                                  statusSource
##                                                                         <chr>
## 1 "<a href=\"http://twitter.com/download/android\" rel=\"nofollow\">Twitter f
## 2    "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>"
## 3 "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter fo
## 4 "<a href=\"https://about.twitter.com/products/tweetdeck\" rel=\"nofollow\">
## 5           "<a href=\"http://instagram.com\" rel=\"nofollow\">Instagram</a>"
## # ... with 1 more variables: n <int>
Pixel2XL_df$statusSource = substr(Pixel2XL_df$statusSource, 
                            regexpr('>', Pixel2XL_df$statusSource) +1,
                            regexpr('</a>', Pixel2XL_df$statusSource) -1)
Pixel2XL_platform <-Pixel2XL_df %>% group_by(statusSource) %>% 
                        summarize(n = n()) %>%
                        mutate(percent_of_tweets = n/sum(n)) %>% 
                        arrange(desc(n))
Pixel2XL_platform %>% top_n(5)
## Selecting by percent_of_tweets
## # A tibble: 5 x 3
##          statusSource     n percent_of_tweets
##                 <chr> <int>             <dbl>
## 1 Twitter for Android   358             0.358
## 2  Twitter Web Client   241             0.241
## 3  Twitter for iPhone   122             0.122
## 4           TweetDeck    57             0.057
## 5           Instagram    33             0.033

It is not surprising that the source with the most tweets referencing Pixel 2XL is “Twitter for Android” (at 35.7%) since Android is the platform used by Pixel phones. However, it is interesting that the majority of the 1,000 tweets we are looking at that reference iPhone X are also coming from “Twitter for Android” (at 36.5%) with “Twitter for iPhone”(at 31.7%) coming in second place. We should keep this in mind when looking at the positive and negative word associations, it may be that more Pixel/Andriod users are saying negative things about the new iPhoneX. This was a conclusion that was drawn from the original analysis. Looking at the results 24 hours later and there is a change in the platforms because the 1,000 tweets being used are live and current. However, as a final conclusion because I will be turning this in now, the source with the most tweets referencing iPhone X is “Twitter for iPhone” (at 33.5%) and in second place is “Twitter for Android” (at 32.5%).

A Closer Look at the Active Users in our Samples

As we can see from the following two figures (Figure 4 and Figure 5), the users tweeting about iPhoneX are less concentrated, meaning the most tweets coming from single user in our sample is 11. While the tweets coming from Pixel 2 XL seem to be more concentrated, with 8 of the top 10 users tweeting 10 times or more and the top user actually tweeting 52 times about the Pixel 2 XL in our data set.

Figure 4: Most Active Users Tweeting About iPhone X

iPhoneX_df %>% group_by(screenName) %>% summarize(n=n()) %>%
    mutate(percent_of_tweets = n/sum(n)) %>%
  arrange(desc(n)) %>%
  top_n(5)
## Selecting by percent_of_tweets
## # A tibble: 6 x 3
##      screenName     n percent_of_tweets
##           <chr> <int>             <dbl>
## 1        nocomp    11             0.011
## 2     awimperia     7             0.007
## 3  AppleNews_it     5             0.005
## 4 MacApple_Newz     5             0.005
## 5     nazerra88     5             0.005
## 6  shadowdogman     5             0.005

Figure 5: Most Active Users Tweeting About Pixel 2XL

Pixel2XL_df %>% group_by(screenName) %>% summarize(n=n()) %>%
    mutate(percent_of_tweets = n/sum(n)) %>%
  arrange(desc(n)) %>%
  top_n(10)
## Selecting by percent_of_tweets
## # A tibble: 10 x 3
##         screenName     n percent_of_tweets
##              <chr> <int>             <dbl>
##  1       Edition29    52             0.052
##  2    AdvRally4K29    10             0.010
##  3 DriverEdition29    10             0.010
##  4     e29networks    10             0.010
##  5   Firas_ALshebl    10             0.010
##  6           IVf29    10             0.010
##  7        MegeByte    10             0.010
##  8   TheDailyMotor    10             0.010
##  9        IDOMIZU_     9             0.009
## 10          xrEvan     7             0.007

After being somewhat intrigued by the Edition29 user, I decided to look more closely at this profile, it seems this user is a “next generation mobile video editorial” page, that focuses on Andriod platforms. Still with their percent of tweets being under 5% (at 4%) it does not seem that either iPhoneX nor Pixel 2XL has any super concentrated users. Update: in the past 24 hours this user has passed 5% and their tweets are weighing more heavily on the results with the word analysis, which we will see later inthe assignment.

Implementing TidyText and Text Analysis

We will now use tidytext to look for individual words so we can start the text/sentiment analysis to determine which phone is “beter.”

Figure 6: The Top 10 Most Used Words in iPhoneX Tweets

reg <- "([^A-Za-z\\d#@']|'(?![A-Za-z\\d#@]))"
iPhoneX_words <- iPhoneX_df %>%
  filter(!str_detect(text, '^"')) %>%
  mutate(text = str_replace_all(text, "https://t.co/[A-Za-z\\d]+|&amp;", "")) %>%
  unnest_tokens(word, text, token = "regex", pattern = reg) %>%
  filter(!word %in% stop_words$word,
         str_detect(word, "[a-z]"))

iPhoneX_words %>% group_by(word) %>% summarize(n = n()) %>% arrange(desc(n)) %>% top_n(20)
## Selecting by n
## # A tibble: 20 x 2
##            word     n
##           <chr> <int>
##  1     #iphonex   960
##  2           rt   715
##  3        brand   298
##  4        tweet   297
##  5     retweets   295
##  6      twitter   295
##  7 @baddicandii   294
##  8         290k   294
##  9       iphone   187
## 10       follow   108
## 11    #giveaway    97
## 12       @apple    94
## 13 #competition    84
## 14         #win    73
## 15        256gb    72
## 16      retweet    72
## 17  @prizesquad    69
## 18           de    62
## 19       #apple    60
## 20        https    57

Figure 7: The Top 10 Most Used Words in Pixel 2 XL Tweets

reg <- "([^A-Za-z\\d#@']|'(?![A-Za-z\\d#@]))"
Pixel2XL_words <- Pixel2XL_df %>%
  filter(!str_detect(text, '^"')) %>%
  mutate(text = str_replace_all(text, "https://t.co/[A-Za-z\\d]+|&amp;", "")) %>%
  unnest_tokens(word, text, token = "regex", pattern = reg) %>%
  filter(!word %in% stop_words$word,
         str_detect(word, "[a-z]"))

Pixel2XL_words %>% group_by(word) %>% summarize(n = n()) %>% arrange(desc(n)) %>% top_n(20)
## Selecting by n
## # A tibble: 20 x 2
##             word     n
##            <chr> <int>
##  1     #pixel2xl   881
##  2            rt   308
##  3         pixel   186
##  4       #google   159
##  5        google   145
##  6            xl   137
##  7       #pixel2   127
##  8       @google   111
##  9    #teampixel   103
## 10      ctreamer   102
## 11     editorial   102
## 12        filmed   102
## 13       reunion    85
## 14      #samsung    82
## 15 #porscheraces    79
## 16     rennsport    74
## 17         phone    69
## 18          #htc    68
## 19      #iphonex    66
## 20           #lg    64

Figure 6 and Figure 7 show us that the most frequently used words in tweets about iPhoneX and Pixel 2 XL are the product names themselves, which is not surprising.

#Using NRC for the sentiment analysis for the word analysis.
nrc <- sentiments %>% 
  filter(lexicon == "nrc") %>%
select(word, sentiment)
head(nrc)
## # A tibble: 6 x 2
##        word sentiment
##       <chr>     <chr>
## 1    abacus     trust
## 2   abandon      fear
## 3   abandon  negative
## 4   abandon   sadness
## 5 abandoned     anger
## 6 abandoned      fear
#joining nrc and iPhone X tweets
iPhoneX_words_sentiments <- iPhoneX_words %>% inner_join(nrc, by = "word")
iPhoneX_words_sentiments %>% group_by(sentiment) %>% summarize(n = n()) %>% arrange(desc(n))
## # A tibble: 10 x 2
##       sentiment     n
##           <chr> <int>
##  1     positive   210
##  2 anticipation   102
##  3     negative    93
##  4          joy    81
##  5        trust    76
##  6     surprise    50
##  7         fear    46
##  8      sadness    39
##  9        anger    37
## 10      disgust    33
#looking at the words that provide positive sentiments in the iPhone X tweets
pos_ids <- iPhoneX_words_sentiments %>% filter(sentiment == "positive") %>% distinct(id)
iPhoneX_df %>% inner_join(pos_ids, by = "id") %>% select(text) %>% slice(1:10)
## # A tibble: 10 x 1
##                                                                                                                      text
##                                                                                                                     <chr>
##  1                                            "RT @TheRealSASHTv: #newvideo was supposed to be up soon but been delayed a
##  2                                            @IGN Well I<U+0092>m happy with #iPhoneX end of the day each &amp; everyone has a 
##  3 "RT @mile_Dolphin: <U+6700><U+901F><U+958B><U+5C01><U+306E><U+5100><U+304B><U+3082>\n#iPhoneX https://t.co/3fDZwUvg0Z"
##  4                                            RT @vidIQ: THANKING ALL 100,000 @YouTube SUBSCRIBERS! ANYONE FANCY AN #iPho
##  5                                            "I played with an #iPhoneX at Target and couldn<U+0092>t get over that awkwardly p
##  6                "Defend...\n#\xed<U+00A0><U+00BD>\xed<U+00B3><U+00B1> #iPhoneX @OtterBox #Defender #Marathoner https://
##  7                                                                         RT @TechGroundES: Qué preferís con el #iPhoneX
##  8                                            RT @CliveTwo: Quand t<U+0092>as acheté l<U+0092>#iPhoneX 1329<U+0080> et que t<U+0092>apprends que son 
##  9                                                   "Primer tweet desde #iphoneX \xed<U+00A0><U+00BD>\xed<U+00B8>\u009d"
## 10                                            Taken with an #iPhoneX and Live Photo long exposure. Makes the California c
#looking at the words that provide negative sentiments in the iPhone X tweets
neg_ids <- iPhoneX_words_sentiments %>% filter(sentiment == "negative") %>% distinct(id)
iPhoneX_df %>% inner_join(neg_ids, by = "id") %>% select(text) %>% slice(1:10)
## # A tibble: 10 x 1
##                                                                           text
##                                                                          <chr>
##  1 "RT @TheRealSASHTv: #newvideo was supposed to be up soon but been delayed a
##  2 "I played with an #iPhoneX at Target and couldn<U+0092>t get over that awkwardly p
##  3 Under-advertised aspect of #iPhoneX - the speakers are fantastic. Unless I<U+0092>
##  4 #iPhoneX und die grünen Linie des Todes - #Displayfehler | https://t.co/WOS
##  5 "RT @techeblog: #Apple #iPhoneX Plus offers massive 6.7\" $OLED display, ke
##  6 So the new #IphoneX looks like its going to be another samsung looks like t
##  7 "#Apple #iPhoneX Plus offers massive 6.7\" $OLED display, keeps dual rear c
##  8 "@instagram stop motion on the #iPhoneX is hard to use because the <U+0093>done<U+0094> o
##  9 RT @iMore: Capture your screen on the #iPhoneX like this! https://t.co/XZVz
## 10 RT @ManxomeMia: And then we proceeded to waste half our day. #animojikaraok
#joining nrc and Pixel 2 XL tweets
Pixel2XL_words_sentiments <- Pixel2XL_words %>% inner_join(nrc, by = "word")
Pixel2XL_words_sentiments %>% group_by(sentiment) %>% summarize(n = n()) %>% arrange(desc(n))
## # A tibble: 10 x 2
##       sentiment     n
##           <chr> <int>
##  1     positive   328
##  2 anticipation   241
##  3        trust   221
##  4     negative   149
##  5          joy   102
##  6        anger    90
##  7      sadness    65
##  8         fear    58
##  9     surprise    57
## 10      disgust    56
#looking at the words that provide positive sentiments in the Pixel 2 XL tweets
pos_ids <- Pixel2XL_words_sentiments %>% filter(sentiment == "positive") %>% distinct(id)
Pixel2XL_df %>% inner_join(pos_ids, by = "id") %>% select(text) %>% slice(1:10)
## # A tibble: 10 x 1
##                                                                           text
##                                                                          <chr>
##  1 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #Hond
##  2 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #Hond
##  3 @madebygoogle the only thing that would make my #pixel2xl better is wireles
##  4 The number of Google #Pixel2XL issues should worry any potential buyer. As 
##  5 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #Hond
##  6 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #Hond
##  7 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #Toyo
##  8 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #Toyo
##  9 RT @AnirbanMoBro: Seems like a forced promotion of   #Pixel2XL through many
## 10 REUNION_CTREAMER. FILMED EDITORIAL. LET IT PLAY. VIDEO. #PorscheRaces #WEC
#looking at the words that provide negative sentiments in the Pixel 2 XL tweets
neg_ids <- Pixel2XL_words_sentiments %>% filter(sentiment == "negative") %>% distinct(id)
Pixel2XL_df %>% inner_join(neg_ids, by = "id") %>% select(text) %>% slice(1:10)
## # A tibble: 10 x 1
##                                                                           text
##                                                                          <chr>
##  1 The number of Google #Pixel2XL issues should worry any potential buyer. As 
##  2 RT @AnirbanMoBro: Seems like a forced promotion of   #Pixel2XL through many
##  3 @Google Im so happy ur #Pixel2XL  #Pixel2  is such a flop. U fraud ppl and 
##  4 @madebygoogle Im so happy ur #Pixel2XL  #Pixel2  is such a flop. U fraud pp
##  5 @madebygoogle Im so happy ur #Pixel2XL  #Pixel2  is such a flop. U fraud pp
##  6 Someone (.@MKBHD ) please tell .@Google to make it a requirement for case m
##  7 "RT @ABHIandNOW: Today's crazy sunset in Dharamsala. \n\n@madebygoogle #tea
##  8 Why is the audio recording so bad on the #GooglePixel2 and #Pixel2XL when r
##  9 "The #Pixel2XL went from <U+0093>the best Android device<U+0094> to a train wreck in 3 we
## 10 https://t.co/mLF7UbO6RO. @engadget anything got click bait. No problems her

Results and Conclusion

In order to determine which phone is “better” based on positive and negative sentiment feedback from the twitter community. We need to combine the data and compare visually.

#Combining iPhoneX and Pixel2XL 
iPhoneX_platform$OS <- "IOS/iPhoneX"
Pixel2XL_platform$OS <- "Android/Pixel2XL"
iPhoneX_words_sentiments$OS <- "IOS/iPhone10"
Pixel2XL_words_sentiments$OS <- "Android/Pixel2XL"
platform <- rbind(iPhoneX_platform, Pixel2XL_platform)
words_sentiments <- rbind(iPhoneX_words_sentiments, Pixel2XL_words_sentiments)

Figure 8: Comparing the Percentage of Tweets Associated with Certain Sentiment Words for iPhoneX vs. Pixel 2XL

sentiments_df <- words_sentiments %>%
  group_by(OS, sentiment) %>% 
  summarise(n = n()) %>%
  mutate(frequency = n/sum(n)*100)

ggplot(sentiments_df, aes(x = sentiment, y = frequency, fill = OS)) + geom_bar(stat = "identity", position = "dodge") +
  geom_text(aes(label=round(frequency, digits =1)), vjust=2.6, color="black", position = position_dodge(0.8), size =3) +
  xlab("sentiment") +
  ylab("Percent of tweets") +
  theme(axis.text.x = element_text(angle =90, hjust =1))

Looking at Figure 8 we can see that there is a higher percentage of positive sentiments related to the Pixel 2 XL vs. the iPhone X. However, there are also more negative sentiments related to the Pixel 2 XL. When we take the positive sentiment percentage and subtract the negative sentiment percentage, we get a higher value for Andriod/Pixel 2XL, which means by our definition in the methodology section, the Pixel 2 XL is the “better” phone. Update: in the past 24 hours this finding has also shifted. Now we see from Figure 8 that there are more poisitve and negative sentiments associated with iPhone X. This means from our definition, which subtracts the negative percentage of tweets from the positive percentage of tweets, the “better” phone is now the iPhone X.

Figure 9: Checking Which Words are Associated with Which Sentiments for iPhoneX

#Checking which words are associated with which sentiments for iPhoneX
bing <- get_sentiments("bing")
iPhoneX_nrc_word_counts <- iPhoneX_words %>% inner_join(bing) %>% count(word, sentiment, sort = TRUE) %>% ungroup()
## Joining, by = "word"
iPhoneX_nrc_word_counts %>% top_n(25)
## Selecting by n
## # A tibble: 39 x 3
##       word sentiment     n
##      <chr>     <chr> <int>
##  1     win  positive    33
##  2    free  positive     8
##  3 buzzing  negative     6
##  4    kill  negative     6
##  5   waste  negative     6
##  6     bad  negative     4
##  7  broken  negative     4
##  8   fancy  positive     4
##  9   handy  positive     4
## 10 popular  positive     4
## # ... with 29 more rows

Figure 10: iPhone X Showing which Words Contributed to the Positive and Negative Sentiment

(for words that appeared more than 3 times)

bing <- get_sentiments("bing")
iPhoneX_nrc_word_counts %>% filter(n>3) %>%
  mutate(n = ifelse(sentiment =="negative", -n, n)) %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill=sentiment)) + 
  geom_bar(stat = "identity") +
  theme(axis.text.x = element_text(angle = 90, hjust =1)) +
  ylab("contribution to sentiment")

Looking more closely at the words that drove the positive and negative sentiment percentage of tweets in Figure 8, Figure 10 shows us that the word “waste” had a significant contribution to the negative sentiment. While “win” and “free” have significant contributions to the postiive sentiment rating for iPhone X.The word “win” may be associated with a positive sentiment through the lexicons (nrc and bing) but here it may be more contextually appropraite to recognize that some sort of contest is likely taking place where the iPhoneX is one of the prizes.

Figure 11: Checking Which Words are Associated with Which Sentiments for Pixel 2 XL

#Checking which words are associated with which sentiments for Pixel 2 XL
Pixel2XL_nrc_word_counts <- Pixel2XL_words %>% inner_join(bing) %>% count(word, sentiment, sort = TRUE) %>% ungroup()
## Joining, by = "word"
Pixel2XL_nrc_word_counts %>% top_n(25)
## Selecting by n
## # A tibble: 37 x 3
##            word sentiment     n
##           <chr>     <chr> <int>
##  1       issues  negative    47
##  2        issue  negative    17
##  3         love  positive    17
##  4         burn  negative    14
##  5        worth  positive    13
##  6          bad  negative    12
##  7         hard  negative    11
##  8         free  positive     9
##  9          win  positive     9
## 10 unresponsive  negative     8
## # ... with 27 more rows

Figure 12: Pixel 2 XL Showing which Words Contributed to the Positive and Negative Sentiment

(for words that appeared more than 3 times)

Pixel2XL_nrc_word_counts %>% filter(n>3) %>%
  mutate(n = ifelse(sentiment =="negative", -n, n)) %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill=sentiment)) + 
  geom_bar(stat = "identity") +
  theme(axis.text.x = element_text(angle = 90, hjust =1)) +
  ylab("contribution to sentiment")

Figure 12 shows us that the words “issues” and “issue” came up quite a bit and contributed to the negative sentiment percentage associated with Pixel 2 XL. On the otherhand, “love” and “worth” contributed to the positive sentiment percentage Pixel 2 XL experienced.

Figure 13: Word Cloud of the most used words in the 1,000 iPhone X Tweets

iPhoneX_words %>%
  count(word) %>%
  with(wordcloud(word, n, max.words =100))

Figure 13 is much like a visual representation of Figure 6, where we can see the most frequently used words out of the most recent 1,000 tweets that discuss iPhone X. Again, the product is the most frequently used word but other words shown tell us a little bit about what is going on in the twitter community around iPhone x. We can see “giveaway” as well as “#win” which clearly indicate that there is some sort of contest going on and iPhone X is the prize.

Figure 14: Word Cloud of Reoccuring sentiments in the 1,000 iPhone X Tweets

iPhoneX_words_sentiments %>%
  count(word) %>%
  with(wordcloud(word, n, max.words =200))

Figure 14 shows us a wordcloud of the sentiments that come up the most in the 1,000 tweets being analyzed, we can see visually that “gift and”finally" came up the most when looking at the sentiments associated with the iPhoneX.

Figure 15: Word Cloud of the most used words in the 1,000 Pixel 2 XL Tweets

Pixel2XL_words %>%
  count(word) %>%
  with(wordcloud(word, n, max.words =100))

Figure 15 is much like a visual representation of Figure 7, where we can see the most frequently used words out of the most recent 1,000 tweets that discuss Pixel 2 XL. Again, the product is the most frequently used word but other words shown tell us a little bit about what is going on in the twitter community around the Pixel 2 XL. We can see once again that the Editor29 user has been active and influencing the most frequently used words, we see “cteamer”“ which is this users personal website.

Figure 16: Word Cloud of Reoccuring sentiments in the 1,000 Pixel 2 XL Tweets

Pixel2XL_words_sentiments %>%
  count(word) %>%
  with(wordcloud(word, n, max.words =200))

Figure 16 shows us a wordcloud of the sentiments that come up the most in the 1,000 tweets being analyzed, we can see visually that “reunion,” which is associated with user Editor29, and “bad” and “finally” came up the most when looking at the sentiments associated with the Pixel 2 XL.

From our standards, which just looked at the positive and negative sentiments associated with each phone (see Figure 8), we can determine the iPhone X is the “better” phone. Although it was a very close race and as time goes on we may see this shift, or be reaffirmed as more users switch away from Apple to Google. Also, with twitter data and only looking at the most recent 1,000 tweets, this information shifted even in the last few hours. It would be interesting to keep track of how this shifts over time and for what reasons.

More Information

If you are currently phone shopping for yourself or someone else, here are some more sources for information:
Trusted Reviews
Tom’s Guide
Stuff
Forbes

Appendix

#Number of time each "positive" word comes up for iPhone X tweets
nrcpos <- get_sentiments("nrc") %>% filter(sentiment == "positive") 
pander(head(iPhoneX_words %>% semi_join(nrcpos) %>% count(word, sort = TRUE)))
## Joining, by = "word"
word n
gift 17
giving 14
join 12
production 12
don 6
finally 5
#Number of time each "positive" word comes up for Pixel 2 XL tweets
nrcpos <- get_sentiments("nrc") %>% filter(sentiment == "positive") 
pander(head(Pixel2XL_words %>% semi_join(nrcpos) %>% count(word, sort = TRUE)))
## Joining, by = "word"
word n
reunion 85
love 17
worth 13
major 11
jump 10
finally 9