Exploring Relationships with DS Labs

Author

George Bothos

Loading and Exploring the DS Labs Datasets

# Loading the packages for data analysis and visualization
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dslabs)

# Displaying the datasets included in the DS Labs package
data(package = "dslabs")

Exploring the MovieLens Dataset

# Loading the MovieLens dataset from DS Labs
data("movielens")

# Previewing the dataset and examining its variables
head(movielens)
  movieId                                   title year
1      31                         Dangerous Minds 1995
2    1029                                   Dumbo 1941
3    1061                                Sleepers 1996
4    1129                    Escape from New York 1981
5    1172 Cinema Paradiso (Nuovo cinema Paradiso) 1989
6    1263                        Deer Hunter, The 1978
                            genres userId rating  timestamp
1                            Drama      1    2.5 1260759144
2 Animation|Children|Drama|Musical      1    3.0 1260759179
3                         Thriller      1    3.0 1260759182
4 Action|Adventure|Sci-Fi|Thriller      1    2.0 1260759185
5                            Drama      1    4.0 1260759205
6                        Drama|War      1    2.0 1260759151
names(movielens)
[1] "movieId"   "title"     "year"      "genres"    "userId"    "rating"   
[7] "timestamp"
str(movielens)
'data.frame':   100004 obs. of  7 variables:
 $ movieId  : int  31 1029 1061 1129 1172 1263 1287 1293 1339 1343 ...
 $ title    : chr  "Dangerous Minds" "Dumbo" "Sleepers" "Escape from New York" ...
 $ year     : int  1995 1941 1996 1981 1989 1978 1959 1982 1992 1991 ...
 $ genres   : Factor w/ 901 levels "(no genres listed)",..: 762 510 899 120 762 836 81 762 844 899 ...
 $ userId   : int  1 1 1 1 1 1 1 1 1 1 ...
 $ rating   : num  2.5 3 3 2 4 2 2 2 3.5 2 ...
 $ timestamp: int  1260759144 1260759179 1260759182 1260759185 1260759205 1260759151 1260759187 1260759148 1260759125 1260759131 ...

Calculating Average Ratings for Each Movie

# Calculating the average rating and number of ratings for each movie
movies_summary <- movielens %>%
  group_by(movieId, title, year, genres) %>%
  summarise(
    avg_rating = mean(rating, na.rm = TRUE),
    rating_count = n(),
    .groups = "drop"
  )

# Previewing the summarized movie data
head(movies_summary)
# A tibble: 6 × 6
  movieId title                        year genres       avg_rating rating_count
    <int> <chr>                       <int> <fct>             <dbl>        <int>
1       1 Toy Story                    1995 Adventure|A…       3.87          247
2       2 Jumanji                      1995 Adventure|C…       3.40          107
3       3 Grumpier Old Men             1995 Comedy|Roma…       3.16           59
4       4 Waiting to Exhale            1995 Comedy|Dram…       2.38           13
5       5 Father of the Bride Part II  1995 Comedy             3.27           56
6       6 Heat                         1995 Action|Crim…       3.88          104

Filtering Movies into Five Genre Categories

# Separating movies with multiple genres into individual categories
movies_filtered <- movies_summary %>%
  mutate(genre = as.character(genres)) %>%
  separate_rows(genre, sep = "\\|") %>%
  filter(genre %in% c("Action", "Comedy", "Drama", "Horror", "Romance")) %>%
  filter(!is.na(year) & !is.na(avg_rating) & !is.na(rating_count))

# Checking the genre categories and number of movies
table(movies_filtered$genre)

 Action  Comedy   Drama  Horror Romance 
   1543    3305    4327     872    1541 
nrow(movies_filtered)
[1] 11588

Visualizing the Movie Ratings Across the Release Years and Genres

# Creating a scatterplot that compares movie release years and average ratings
ggplot(movies_filtered, aes(x = year, y = avg_rating,
                            color = genre, size = rating_count)) +
  geom_point(alpha = 0.5) +
  scale_color_brewer(palette = "Set1") +
  scale_size(range = c(1, 7)) +
  theme_minimal() +
  labs(
    title = "Movie Ratings Across Release Years and Genres",
    subtitle = "Comparing average ratings, genres, and popularity",
    x = "Movie Release Year",
    y = "Average Movie Rating (1–5)",
    color = "Movie Genre",
    size = "Number of Ratings",
    caption = "Source: DS Labs MovieLens Dataset"
  )

Analysis and Interpretation

I decided to use the MovieLens dataset from the DS Labs package for this assignment. This dataset contained information about movie ratings, release years, and genres. I decided to first group the ratings by movie so that I could calculate each movie’s average rating and the number of ratings it had received.

Some of the movies belonged to multiple genres, and so I separated those categories and focused on action, comedy, drama, horror, and romance. I was also able to remove observations with missing values before I created my visualization.

My scatter plot compares the movie release years and average ratings, and it uses different colors to represent genres. Larger points represent movies that have more ratings. Something that I found interesting was that there are considerably more movie observations from recent years compared to older years. Something else that I also noticed is that average ratings vary quite a bit within each genre, which suggests to me that genre alone does not determine how highly a movie is rated.

Overall, though, the graph shows how multiple variables can be combined to better understand patterns in movie ratings.