# Uploading the data ----
library(ggplot2)
library(data.table)
hotels <- readRDS(url('http://bit.ly/CEU-R-hotels-2018-merged'))
hotels
## hotel_id city distance stars rating country city_actual
## 1: 1 Amsterdam 3.1 4.0 4.3 Netherlands Amsterdam
## 2: 3 Amsterdam 1.5 4.0 4.1 Netherlands Amsterdam
## 3: 4 Amsterdam 1.9 3.0 3.5 Netherlands Amsterdam
## 4: 5 Amsterdam 1.8 3.5 4.0 Netherlands Amsterdam
## 5: 6 Amsterdam 1.9 4.0 4.1 Netherlands Amsterdam
## ---
## 22897: 22898 Zagreb 0.2 2.0 3.7 Croatia Zagreb
## 22898: 22899 Zagreb 4.0 3.0 NA Croatia Zagreb
## 22899: 22900 Zagreb 3.9 4.0 4.4 Croatia Zagreb
## 22900: 22901 Zagreb 3.3 3.0 3.5 Croatia Zagreb
## 22901: 22902 Zagreb 1.1 4.0 4.5 Croatia Zagreb
## rating_count center1label center2label neighbourhood ratingta
## 1: 1030 City centre Montelbaanstoren Amsterdam 4.0
## 2: 165 City centre Montelbaanstoren Amsterdam 4.0
## 3: 298 City centre Montelbaanstoren Amsterdam 3.5
## 4: 4 City centre Montelbaanstoren Amsterdam 4.5
## 5: 310 City centre Montelbaanstoren Amsterdam 4.0
## ---
## 22897: 36 City centre Zagreb City Museum Zagreb 3.5
## 22898: NA City centre Zagreb City Museum Zagreb NA
## 22899: 9 City centre Zagreb City Museum Zagreb 4.5
## 22900: 24 City centre Zagreb City Museum Zagreb 3.0
## 22901: 48 City centre Zagreb City Museum Zagreb 4.5
## ratingta_count distance_alter accommodation_type avg_price_per_night
## 1: 1115 3.6 Hotel 131.66667
## 2: 674 1.4 Hotel 150.05000
## 3: 1882 2.1 Hotel 93.00000
## 4: 66 2.0 Hotel 792.77500
## 5: 767 2.0 Hotel 197.46429
## ---
## 22897: 42 0.4 Hostel 34.02500
## 22898: NA 4.0 Apartment 77.08333
## 22899: 225 3.9 Hotel 124.41667
## 22900: 14 3.3 Hotel 94.18750
## 22901: 86 0.6 Hotel 117.64286
## sd_price_per_night bookings
## 1: 21.257156 6
## 2: 47.621030 5
## 3: 31.112698 2
## 4: 113.754148 10
## 5: 66.940339 7
## ---
## 22897: 2.809829 10
## 22898: 0.250000 9
## 22899: 15.199370 3
## 22900: 0.375000 4
## 22901: 14.418490 7
# Data exploration ----
str(hotels)
## Classes 'data.table' and 'data.frame': 22901 obs. of 18 variables:
## $ hotel_id : int 1 3 4 5 6 7 8 9 10 11 ...
## $ city : chr "Amsterdam" "Amsterdam" "Amsterdam" "Amsterdam" ...
## $ distance : num 3.1 1.5 1.9 1.8 1.9 0.8 0.9 1 1.8 2.2 ...
## $ stars : num 4 4 3 3.5 4 3.5 4 4 4 3 ...
## $ rating : num 4.3 4.1 3.5 4 4.1 4.4 4.8 4.4 3.7 3.7 ...
## $ country : chr "Netherlands" "Netherlands" "Netherlands" "Netherlands" ...
## $ city_actual : chr "Amsterdam" "Amsterdam" "Amsterdam" "Amsterdam" ...
## $ rating_count : int 1030 165 298 4 310 258 210 967 6 341 ...
## $ center1label : chr "City centre" "City centre" "City centre" "City centre" ...
## $ center2label : chr "Montelbaanstoren" "Montelbaanstoren" "Montelbaanstoren" "Montelbaanstoren" ...
## $ neighbourhood : chr "Amsterdam" "Amsterdam" "Amsterdam" "Amsterdam" ...
## $ ratingta : num 4 4 3.5 4.5 4 4.5 4.5 4.5 NA 3.5 ...
## $ ratingta_count : int 1115 674 1882 66 767 273 298 6452 NA 435 ...
## $ distance_alter : num 3.6 1.4 2.1 2 2 1.2 0.8 0.5 1.8 1.9 ...
## $ accommodation_type : chr "Hotel" "Hotel" "Hotel" "Hotel" ...
## $ avg_price_per_night: num 132 150 93 793 197 ...
## $ sd_price_per_night : num 21.3 47.6 31.1 113.8 66.9 ...
## $ bookings : int 6 5 2 10 7 4 2 9 2 6 ...
## - attr(*, ".internal.selfref")=<externalptr>
## - attr(*, "sorted")= chr "hotel_id"
summary(hotels)
## hotel_id city distance stars
## Min. : 1 Length:22901 Min. : 0.000 Min. :1.000
## 1st Qu.: 5727 Class :character 1st Qu.: 0.700 1st Qu.:3.000
## Median :11452 Mode :character Median : 1.300 Median :3.000
## Mean :11452 Mean : 2.784 Mean :3.297
## 3rd Qu.:17177 3rd Qu.: 2.600 3rd Qu.:4.000
## Max. :22902 Max. :57.000 Max. :5.000
## NA's :5715
## rating country city_actual rating_count
## Min. :1.000 Length:22901 Length:22901 Min. : 1.0
## 1st Qu.:3.500 Class :character Class :character 1st Qu.: 18.0
## Median :4.000 Mode :character Mode :character Median : 63.0
## Mean :3.903 Mean : 136.9
## 3rd Qu.:4.400 3rd Qu.: 161.0
## Max. :5.000 Max. :4300.0
## NA's :2180 NA's :2180
## center1label center2label neighbourhood ratingta
## Length:22901 Length:22901 Length:22901 Min. :1.000
## Class :character Class :character Class :character 1st Qu.:3.500
## Mode :character Mode :character Mode :character Median :4.000
## Mean :3.945
## 3rd Qu.:4.500
## Max. :5.000
## NA's :2993
## ratingta_count distance_alter accommodation_type avg_price_per_night
## Min. : 0.0 Min. : 0.00 Length:22901 Min. : 7.75
## 1st Qu.: 53.0 1st Qu.: 1.10 Class :character 1st Qu.: 77.86
## Median : 184.0 Median : 2.70 Mode :character Median : 111.00
## Mean : 435.4 Mean : 4.52 Mean : 138.56
## 3rd Qu.: 530.0 3rd Qu.: 6.00 3rd Qu.: 163.62
## Max. :17139.0 Max. :65.00 Max. :3714.07
## NA's :2993
## sd_price_per_night bookings
## Min. : 0.000 Min. : 1.000
## 1st Qu.: 8.661 1st Qu.: 3.000
## Median : 20.440 Median : 7.000
## Mean : 33.111 Mean : 6.463
## 3rd Qu.: 38.268 3rd Qu.:10.000
## Max. :4944.500 Max. :10.000
## NA's :2413
colSums(is.na(hotels))
## hotel_id city distance stars
## 0 0 0 5715
## rating country city_actual rating_count
## 2180 0 0 2180
## center1label center2label neighbourhood ratingta
## 0 0 0 2993
## ratingta_count distance_alter accommodation_type avg_price_per_night
## 2993 0 0 0
## sd_price_per_night bookings
## 2413 0
colnames(hotels)
## [1] "hotel_id" "city" "distance"
## [4] "stars" "rating" "country"
## [7] "city_actual" "rating_count" "center1label"
## [10] "center2label" "neighbourhood" "ratingta"
## [13] "ratingta_count" "distance_alter" "accommodation_type"
## [16] "avg_price_per_night" "sd_price_per_night" "bookings"
#1. How many hotels are from Austria? ----
nrow(hotels[country == 'Austria'])
## [1] 855
# Answer: 855
#2. What is the rating of the most expensive hotel (based on the price per night)? ----
hotels[order(avg_price_per_night, decreasing = TRUE)][1,rating]
## [1] 1.5
# Answer: 1.5
#3. How many bookings are in 4-star hotels? ----
sum(hotels$bookings[hotels$stars == 4.0], na.rm = TRUE) #na.rm is to handle NAs
## [1] 38784
# Answer: 38784
#4. Which country has the highest number of 5-star hotels? ----
sort(table(hotels$country[hotels$stars == 5]), decreasing = TRUE)
##
## United Kingdom Italy Turkey France Spain
## 129 101 96 94 69
## Germany Portugal Russia Czech Republic Austria
## 54 52 47 42 38
## Greece Poland Netherlands Croatia Hungary
## 29 27 26 22 17
## Latvia Belgium Ireland Romania Bulgaria
## 11 10 10 10 9
## Ukraine Lithuania Slovakia Sweden Belarus
## 8 7 7 7 6
## Estonia Serbia Denmark Finland Malta
## 6 5 2 2 1
names(sort(table(hotels$country[hotels$stars == 5]), decreasing = TRUE))[1]
## [1] "United Kingdom"
# Answer: United Kingdom
#5. Plot the number of bookings per country! ----
ggplot(data = hotels, aes(x = country, y = bookings)) + geom_bar(stat = "summary", fun = "sum")

#6. Flip the coordinates and use the "classic dark-on-light theme"! ----
ggplot(data = hotels, aes(x = country, y = bookings)) +
geom_bar(stat = "summary", fun = "sum") +
coord_flip() + theme_classic()

#7. Drop the Y axis title, and rename the X axis to "Number of hotels"! ----
# Notice it's number of hotels now, instead of bookings
ggplot(data = hotels, aes(x = country)) + geom_bar() +
coord_flip() + theme_classic() + labs(x = "", y = "Number of hotels")

#8. Count the number of hotels per country! ----
hotels_per_country <- aggregate(hotels$hotel_id, by=list(Country=hotels$country), FUN=length)
colnames(hotels_per_country)[2] <- "Hotels"
hotels_per_country
## Country Hotels
## 1 Austria 855
## 2 Belarus 51
## 3 Belgium 333
## 4 Bulgaria 101
## 5 Cameroon 1
## 6 Croatia 241
## 7 Czech Republic 635
## 8 Denmark 121
## 9 Egypt 1
## 10 Estonia 90
## 11 Finland 103
## 12 France 2708
## 13 Germany 1196
## 14 Greece 369
## 15 Hungary 340
## 16 Ireland 309
## 17 Italy 6490
## 18 Latvia 131
## 19 Lithuania 88
## 20 Malta 35
## 21 Netherlands 522
## 22 Poland 776
## 23 Portugal 670
## 24 Romania 131
## 25 Russia 1097
## 26 Serbia 111
## 27 Slovakia 104
## 28 Spain 1774
## 29 Sweden 259
## 30 Turkey 1377
## 31 Ukraine 134
## 32 United Kingdom 1748
#9. Order by alphabet! ----
hotels_per_country[order(hotels_per_country$Country),]
## Country Hotels
## 1 Austria 855
## 2 Belarus 51
## 3 Belgium 333
## 4 Bulgaria 101
## 5 Cameroon 1
## 6 Croatia 241
## 7 Czech Republic 635
## 8 Denmark 121
## 9 Egypt 1
## 10 Estonia 90
## 11 Finland 103
## 12 France 2708
## 13 Germany 1196
## 14 Greece 369
## 15 Hungary 340
## 16 Ireland 309
## 17 Italy 6490
## 18 Latvia 131
## 19 Lithuania 88
## 20 Malta 35
## 21 Netherlands 522
## 22 Poland 776
## 23 Portugal 670
## 24 Romania 131
## 25 Russia 1097
## 26 Serbia 111
## 27 Slovakia 104
## 28 Spain 1774
## 29 Sweden 259
## 30 Turkey 1377
## 31 Ukraine 134
## 32 United Kingdom 1748
#10. Count the number of bookings per country, order by the number of bookings! ----
bookings_per_country <- aggregate(hotels$bookings,
by=list(Country=hotels$country),
FUN=sum)
colnames(bookings_per_country)[2] <- "Bookings"
bookings_per_country[order(bookings_per_country$Bookings),]
## Country Bookings
## 9 Egypt 1
## 5 Cameroon 10
## 20 Malta 253
## 2 Belarus 389
## 19 Lithuania 725
## 10 Estonia 746
## 11 Finland 813
## 4 Bulgaria 840
## 27 Slovakia 847
## 8 Denmark 903
## 31 Ukraine 930
## 26 Serbia 972
## 24 Romania 1118
## 18 Latvia 1144
## 6 Croatia 1380
## 16 Ireland 1529
## 29 Sweden 2076
## 3 Belgium 2535
## 15 Hungary 2683
## 21 Netherlands 2803
## 14 Greece 3115
## 7 Czech Republic 3860
## 23 Portugal 4599
## 1 Austria 5333
## 22 Poland 5759
## 25 Russia 8995
## 13 Germany 9087
## 28 Spain 11235
## 30 Turkey 11945
## 32 United Kingdom 12178
## 12 France 22511
## 17 Italy 26704
#11. Compute the average rating per number of stars! Use the weighted.mean function to account for the number of ratings of the hotels, and experiment with the na.rm argument. Eliminate NAs. Order by stars. ----
comp_average <- aggregate(rating ~ stars, data = hotels, FUN = weighted.mean, na.rm = TRUE)
#12. Plot this computed average rating per stars! ----
ggplot(comp_average, aes(x = stars, y = rating)) + geom_bar(stat = "identity")

#13. Make sure that each star category is printed on the X axis! ----
ggplot(comp_average, aes(x = factor(stars), y = rating)) +
geom_bar(stat = "identity") + xlab("") + ggtitle("Rating per number of stars")

#14. Create a boxplot on ratings per stars! ----
ggplot(hotels, aes(x = factor(stars), y = rating)) +
geom_boxplot() +
labs(
title = "Boxplot of Ratings per Stars",
x = "",
y = "Rating"
)
## Warning: Removed 2180 rows containing non-finite values (`stat_boxplot()`).

#15. Create histograms on the nightly prices for each star category! Check out the arguments and disable forcing the same Y axis range for the subplots. ----
ggplot(hotels, aes(x = avg_price_per_night)) +
geom_histogram(binwidth = 50) +
facet_wrap(~ stars, scales = "free") +
labs(
title = "Histograms of Nightly Prices per Stars",
x = "Average Price per Night",
y = "Frequency"
)
