Setup

In this script, we will plot the ratings for reviews containing “good” and “bad”.

First, load packages:

library(tidyverse)
library(tidytext)

Second, load data:

yelp <- read_csv('../data/yelp_10000.csv')

# Check:

yelp
## # A tibble: 10,000 × 10
##    review_id       user_id business_id stars date       text  useful funny  cool
##    <chr>           <chr>   <chr>       <dbl> <date>     <chr>  <dbl> <dbl> <dbl>
##  1 sogB_MLmc39H43… rXWgfR… Zf7jXc_KX0…     1 2016-10-25 "Tha…      5     1     1
##  2 zbDuKvpGbefBLt… Pzhwvq… RCxgxuzyqi…     2 2017-09-07 "The…      0     0     0
##  3 wa-qLnLL0vnmrG… tI20gp… IqBoGCKUJd…     5 2012-05-20 "Usu…      1     0     1
##  4 X1PseScMWXGu7x… 7Aujzd… BdSCZkjNh_…     5 2016-04-28 "I c…      0     0     0
##  5 M-oN06TVi5mhO4… Yl7OYd… GI25Ykbpfy…     5 2015-05-06 "RUM…      0     0     0
##  6 zKPPwn6nZZt2Ko… ldMs4h… BToSTEiaK9…     5 2014-02-19 "Ver…      0     0     1
##  7 Sorep2CIhmypCI… Xyny4Q… EHXCJ7ZEUW…     4 2016-12-21 "Too…      0     0     0
##  8 T3UUi0NZVn_P4i… S-eWud… P7pxQFqr7y…     4 2011-06-03 "Gre…      0     0     0
##  9 2kC1vEJJuZ3rly… r_PURf… uHUcYpGlcd…     1 2016-07-01 "Suc…      3     0     0
## 10 LEsk0tz1dF4HJp… 7qS1iD… u1qzJu0Jwb…     5 2013-07-31 "I c…      0     0     0
## # ℹ 9,990 more rows
## # ℹ 1 more variable: Language <chr>

Check the language column:

yelp %>% count(Language)
## # A tibble: 1 × 2
##   Language     n
##   <chr>    <int>
## 1 english  10000

Get rid of unwanted columns:

yelp <- select(yelp, review_id, stars, text)

Unnest tokens:

yelp <- unnest_tokens(yelp, word, text)

# Check:

yelp
## # A tibble: 1,160,714 × 3
##    review_id              stars word  
##    <chr>                  <dbl> <chr> 
##  1 sogB_MLmc39H43UcH29qxg     1 thank 
##  2 sogB_MLmc39H43UcH29qxg     1 you   
##  3 sogB_MLmc39H43UcH29qxg     1 for   
##  4 sogB_MLmc39H43UcH29qxg     1 the   
##  5 sogB_MLmc39H43UcH29qxg     1 follow
##  6 sogB_MLmc39H43UcH29qxg     1 up    
##  7 sogB_MLmc39H43UcH29qxg     1 but   
##  8 sogB_MLmc39H43UcH29qxg     1 no    
##  9 sogB_MLmc39H43UcH29qxg     1 thank 
## 10 sogB_MLmc39H43UcH29qxg     1 you   
## # ℹ 1,160,704 more rows

Reduce to “good” and “bad”:

good_bad <- filter(yelp,
                   word %in% c('good', 'bad'))

# Check:

good_bad
## # A tibble: 6,013 × 3
##    review_id              stars word 
##    <chr>                  <dbl> <chr>
##  1 sogB_MLmc39H43UcH29qxg     1 good 
##  2 zbDuKvpGbefBLtp_kRKm8g     2 bad  
##  3 zKPPwn6nZZt2KoFrAwKeqw     5 good 
##  4 2kC1vEJJuZ3rlybgHDI53A     1 good 
##  5 E3NhbgS0R5YOJ5Rhz-YMZw     5 good 
##  6 kkt8ewlnt8D2RB95vfI3AA     4 good 
##  7 3WBeMOklPf0woEH58pMNrQ     5 good 
##  8 gl8bt170IxhDc5xYkB0aMQ     5 good 
##  9 gl8bt170IxhDc5xYkB0aMQ     5 good 
## 10 gl8bt170IxhDc5xYkB0aMQ     5 good 
## # ℹ 6,003 more rows

Descriptive statistics

Compute averages:

good_bad %>% group_by(word) %>% 
  summarize(M = mean(stars),
            SD = sd(stars))
## # A tibble: 2 × 3
##   word      M    SD
##   <chr> <dbl> <dbl>
## 1 bad    2.78  1.44
## 2 good   3.71  1.18

Make a plot of this. First, let’s create counts:

counts <- good_bad %>% 
  count(word, stars)

# Check:

counts
## # A tibble: 10 × 3
##    word  stars     n
##    <chr> <dbl> <int>
##  1 bad       1   230
##  2 bad       2   160
##  3 bad       3   147
##  4 bad       4   163
##  5 bad       5   135
##  6 good      1   367
##  7 good      2   492
##  8 good      3   938
##  9 good      4  1878
## 10 good      5  1503

Columns:

counts %>% 
  ggplot(aes(x = stars, y = n, fill = word)) +
  geom_col(position = 'dodge') +
  scale_y_continuous(limits = c(0, 2500), expand = c(0, 0)) +
  scale_fill_manual(values = c('tomato3', 'skyblue')) +
  theme_classic()