library(tidyverse)
setwd("C:/Users/justi/OneDrive/Desktop/Grad School/UTSA 1st semester/STA 6443 Statistical Modeling/Midterm")
housing_data <- read.csv("ames_housing_data-1.csv") ANOVA
Installed Packages:
To begin, I loaded the tidyverse package and set the working directory to where my data was located. Lastly, I created a dataframe called housing_data to store the data. Next, I performed an exploratory data analysis on the housing data with the goal of being able to fit this data into regression models and predict housing prices using the variable SalePrice.
1. Univariate Analysis
To begin my EDA I created a data frame called eda with the purpose of narrowing down the variables within the housing dataset. I restricted my analysis to only focus on these variables: SalePrice, GrLivArea, LotArea, OverallQual, YearBuilt, GarageCars, Neighborhood, CentralAir. I renamed this revised dataset “eda.”
eda <- housing_data |> select(SalePrice, GrLivArea, LotArea, OverallQual, YearBuilt, GarageCars, Neighborhood, CentralAir)Data Dictionary
SalePrice: The price the house sold for (dependent variable)
GrLivArea: Above grade (ground) living area square feet
LotArea: Lot size in square feet
OverallQual: Rates the overall material and finish of the house (1-10 scale)
YearBuilt: Original construction date
GarageCars: Size of garage in car capacity
Neighborhood: Physical locations within Ames city limits (categorical)
CentralAir: Central air conditioning (Yes or No)
Next, I ran a histogram plot to observe the distribution of the our dependant variable in this analysis. Sale price will be the dependant variable for this analysis
eda |> ggplot(aes(x=SalePrice)) +
geom_histogram(fill = "darkgreen", color = "black") +
labs(title = "Sales Price Distribution")Takeaway: This graph uncovers that this data is right skewed, meaning that the majority of sales price values are in the low to moderate range within this dataset
Next, I evaluated the distribution of the independent variables.
eda |> ggplot(aes(x=OverallQual)) +
geom_histogram(fill = "darkgreen", color = "black", bins = 30) +
labs(
title = "Overall Quality Distribution",
x = "Overall Quality",
y = "Count"
)Takeaway: This graph shows that we will be working with a majority of houses in the 5-7 point quality range.
eda |> ggplot(aes(x=YearBuilt)) +
geom_histogram(fill = "darkgreen", color = "black") +
labs(
title = "Year Built Distribution",
x = "Year Built",
y = "Count"
) +
scale_x_continuous(breaks = seq(1870, 2020, by = 20))Takeaway: This graph shows a pretty even number of houses built in the 50s-70s and then uncovers a massive spike in houses built in the early 2000s.
eda |>
filter(LotArea <= 50000) |>
ggplot(aes(x=LotArea)) +
geom_histogram(fill = "darkgreen", color = "black", bins = 30) +
labs(
title = "Lot Area Distribution",
x = "Lot Area",
y = "Count"
) + scale_x_continuous(
breaks = seq(0, max(eda$LotArea, na.rm = TRUE), by = 10000))Takeaway: The lot area data is normally distributed in one section and then it right skews. There are many outliers in the 40,000- 100,000 area range but I have applied the filter to normalize the data.
Next, I ran a summary function to evaluate the dependant variable and the categorical variables further.
eda |> summary(SalePrice) SalePrice GrLivArea LotArea OverallQual
Min. : 34900 Min. : 334 Min. : 1300 Min. : 1.000
1st Qu.:129975 1st Qu.:1130 1st Qu.: 7554 1st Qu.: 5.000
Median :163000 Median :1464 Median : 9478 Median : 6.000
Mean :180921 Mean :1515 Mean : 10517 Mean : 6.099
3rd Qu.:214000 3rd Qu.:1777 3rd Qu.: 11602 3rd Qu.: 7.000
Max. :755000 Max. :5642 Max. :215245 Max. :10.000
YearBuilt GarageCars Neighborhood CentralAir
Min. :1872 Min. :0.000 Length:1460 Length:1460
1st Qu.:1954 1st Qu.:1.000 Class :character Class :character
Median :1973 Median :2.000 Mode :character Mode :character
Mean :1971 Mean :1.767
3rd Qu.:2000 3rd Qu.:2.000
Max. :2010 Max. :4.000
Takeaway: The SalePrice mean is 214,000 with the min being 34k and the max being 755k. This wide range shows that this sales price data is going to show us a wide variation of sales prices throughout our analysis.
2. Bivariet Analysis
In phase 2 of my EDA, I investigate the relationships between the dependent variable and the independent variables.
cor(eda$SalePrice, eda$GrLivArea)[1] 0.7086245
cor(eda$SalePrice, eda$OverallQual)[1] 0.7909816
cor(eda$SalePrice, eda$LotArea)[1] 0.2638434
cor(eda$SalePrice, eda$GarageCars)[1] 0.6404092
cor(eda$SalePrice, eda$YearBuilt)[1] 0.5228973
cor(eda$OverallQual, eda$GarageCars)[1] 0.6006707
Takeaway: The strongest correlation is between Sale Price and Overall Quality of .79. I also discovered a medium correlation between two independent variables Overall Quality and GarageCars of .64.
I explore our strongest correlation between Sale Price and Overall quality here…
eda |> ggplot(aes(x=OverallQual, y=SalePrice)) +
geom_point(color="darkgreen") +
geom_smooth(method = "lm", se = FALSE, color = "black") +
labs(title = "Relationship between Sale Price and Overall Quality")Takeaway: As quality score increase on the 1-10 scale, sale price increases in a linear fashion with it.
I explore our next strongest corellation here by filtering out the GrLivArea to less than 3,000 sqft to eliminate outliers.
eda |> filter(GrLivArea <= 3000) |>
ggplot(aes(x=SalePrice, y=GrLivArea)) +
geom_point(color = "darkblue") +
labs(
title = "Relationship between Sale Price and Above grade (ground) living area"
)Takeaway: This data reveals that Sale Price and Above grade (ground) living area are positively correlated with most of the datapoints moving in linear fasion.
Next, I evaluate the relationship between our dependant variable and one of the categorical variables, cenralair.
eda |> ggplot(aes(x=CentralAir, y=SalePrice)) +
geom_boxplot(fill = "lightgreen", color = "black") +
labs(title = "Relationship between Sale Price and Air Conditioning")Takeaway: Most of the high value properties contrain central air conditioning units.
Next, I investigate the relationship between Sale Price, GrLivArea, and Overall Quality.
eda |> ggplot(aes(x = GrLivArea, y = SalePrice, color= OverallQual)) +
geom_point() +
labs(title = "Sale price relationship between GrLivArea and Overall Quality")Takeaway: This graph shows that the larger the above ground living area is, the better the quality, AND the higher the sales price tend to be.
3. Data Cleaning and Transformation
For data cleaning, I checked for outliers within the categorical variables, null values, and references the above charts to take note of any outliers. The outliers I found were in GrLivArea and Lot Area.
eda |> summarize(CentralAir_nulls = sum(is.na(CentralAir)), Neighborhood_nulls = sum(is.na(Neighborhood))) CentralAir_nulls Neighborhood_nulls
1 0 0
colSums(is.na(eda)) SalePrice GrLivArea LotArea OverallQual YearBuilt GarageCars
0 0 0 0 0 0
Neighborhood CentralAir
0 0
Additionally, I changed row names in the neighborhood column for uniformity.
unique(eda$Neighborhood) [1] "CollgCr" "Veenker" "Crawfor" "NoRidge" "Mitchel" "Somerst" "NWAmes"
[8] "OldTown" "BrkSide" "Sawyer" "NridgHt" "NAmes" "SawyerW" "IDOTRR"
[15] "MeadowV" "Edwards" "Timber" "Gilbert" "StoneBr" "ClearCr" "NPkVill"
[22] "Blmngtn" "BrDale" "SWISU" "Blueste"
eda <- eda |> mutate(Neighborhood = str_to_title(Neighborhood))4. Feature Selection
I believe based off their high correlation with Sale price, that GrLivArea and OverallQual will be the most important variables for predicting sale price in a model. The positive linear relationship that these variables showed in the bivariate analysis prove that these variables can be accurate predictors for sale price.
Part 2.
I added a column to the EDA dataset to conduct a one way ANOVA test called Location. This location column shows the neighborhoods categorized as North, South, or West.
eda2.0 <- eda |> group_by(Neighborhood) |>
mutate(Location = case_when(
Neighborhood %in% c(
"Blmngtn", "Brdale", "Brkside", "Gilbert", "Idotrr",
"Names", "Noridge", "Npkvill", "Nridght",
"Nwames", "Oldtown", "Somerst", "Stonebr") ~ "North",
Neighborhood %in% c(
"Meadowv", "Mitchel", "Timber") ~ "South",
Neighborhood %in% c(
"Blueste", "Clearcr", "Collgcr", "Crawfor", "Edwards",
"Swisu", "Sawyer", "Sawyerw", "Veenker") ~ "West"))AVOVA
Purpose: The purpose of this ANOVA test will be to determine if there is a statistically significant difference in sales between the North, South, and West locations.
Null Hypotheses:
There is no difference in mean Sale Price across all locations (North, South, West).
Alternative Hypotheses:
There is a difference in mean across at least one location.
First off, I used as.factor to change the categorical variables to factors. Next, I gathered the means of saleprice across location.
eda2.0$Neighborhood<-as.factor(eda2.0$Neighborhood)
eda2.0 |> group_by(Location) |> summarize(mean_location = mean(SalePrice))# A tibble: 3 × 2
Location mean_location
<chr> <dbl>
1 North 185514.
2 South 178254.
3 West 173613.
Next, I created a boxplot to show North, South, and West group means.
eda2.0 |> ggplot(aes(x = Location, y = SalePrice)) +
geom_boxplot(fill = "lightblue", color = "black") +
labs(title = "Location Group Means",
x = "Sale Price",
y = "Location") +
theme_minimal()Next, I conducted the ANOVA test and a Tukeys test to be sure of the results.
oneway <- aov(SalePrice ~ Location , data = eda2.0)
summary(oneway) Df Sum Sq Mean Sq F value Pr(>F)
Location 2 4.551e+10 2.275e+10 3.618 0.0271 *
Residuals 1457 9.162e+12 6.289e+09
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Conclusion: We can conclude from the P > .0271 value that the P value is significant As a result, to reject the null hypothesis and must dig deeper to find which means are different.
To do this, I perform a tukeys test…
TukeyHSD(oneway) Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = SalePrice ~ Location, data = eda2.0)
$Location
diff lwr upr p adj
South-North -7260.043 -26579.91 12059.822 0.6520065
West-North -11901.670 -22373.68 -1429.662 0.0211474
West-South -4641.627 -24692.76 15409.501 0.8500174
Takeaway: According to the p = .0211474 value, there is significant difference in North and West sales prices. There is no statistical evidence to support the other locations sales prices having any significant difference.
Two Way ANOVA
Null Hypotheses We test two null hypothesis in this test:
- There is no difference in mean Sale Price across all locations (North, South, West).
- The mean Sale Price is the same across all years houses were built in.
Alternative Hypotheses:
- There is a difference in mean across at least one location.
- Thrre is a difference in mean sale price accross years build.
To begin my test I grouped the year build column into decade long buckets.
eda2.0$YearBuilt <- paste0(floor(eda2.0$YearBuilt / 10) * 10, "-", floor(eda2.0$YearBuilt / 10) * 10 + 9)Next, I looked a boxplot graph that shows the means of all of our decades.
eda2.0 |> ggplot(aes(x = YearBuilt, y = SalePrice, fill = YearBuilt)) +
geom_boxplot(fill = "lightblue", color = "black") +
labs(title = "Year Built Means",
x = "Sale Price",
y = "Year Built") +
theme_minimal()Next, I run the two way ANOVA model…
twoway <- aov(SalePrice ~ YearBuilt+Location, data = eda2.0)
summary(twoway) Df Sum Sq Mean Sq F value Pr(>F)
YearBuilt 14 3.232e+12 2.309e+11 56.437 < 2e-16 ***
Location 2 7.198e+10 3.599e+10 8.797 0.000159 ***
Residuals 1443 5.903e+12 4.091e+09
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Takeaway: Both of our p values are significant! Meaning we reject both of the null hypothesis. There is statistical evidence to support location and year build impacting sale price.
Next, I run a tukeys test to look deeper…
tukeys <- TukeyHSD(twoway)
print(tukeys) Tukey multiple comparisons of means
95% family-wise confidence level
Fit: aov(formula = SalePrice ~ YearBuilt + Location, data = eda2.0)
$YearBuilt
diff lwr upr p adj
1880-1889-1870-1879 62425.571 -111794.395 236645.538 0.9968518
1890-1899-1870-1879 108316.667 -69100.264 285733.597 0.7521985
1900-1909-1870-1879 21828.400 -141741.928 185398.728 1.0000000
1910-1919-1870-1879 23511.483 -132762.730 179785.696 0.9999999
1920-1929-1870-1879 15268.351 -139955.132 170491.833 1.0000000
1930-1939-1870-1879 36415.833 -120051.192 192882.859 0.9999783
1940-1949-1870-1879 18887.481 -136692.837 174467.799 1.0000000
1950-1959-1870-1879 32935.671 -121629.205 187500.546 0.9999928
1960-1969-1870-1879 45852.640 -108670.420 200375.700 0.9996021
1970-1979-1870-1879 44828.335 -109634.346 199291.016 0.9996919
1980-1989-1870-1879 82080.328 -74065.739 238226.395 0.9038411
1990-1999-1870-1879 120404.221 -34183.097 274991.539 0.3399516
2000-2009-1870-1879 134046.416 -19997.663 288090.495 0.1723779
2010-2019-1870-1879 286432.000 20306.605 552557.395 0.0211297
1890-1899-1880-1889 45891.095 -74998.165 166780.356 0.9943177
1900-1909-1880-1889 -40597.171 -140059.216 58864.873 0.9884627
1910-1919-1880-1889 -38914.089 -125857.035 48028.857 0.9732696
1920-1929-1880-1889 -47157.221 -132197.068 37882.627 0.8612030
1930-1939-1880-1889 -26009.738 -113298.776 61279.300 0.9995827
1940-1949-1880-1889 -43538.090 -129227.539 42151.359 0.9250576
1950-1959-1880-1889 -29489.901 -113321.559 54341.758 0.9974043
1960-1969-1880-1889 -16572.931 -100327.468 67181.605 0.9999972
1970-1979-1880-1889 -17597.236 -101240.323 66045.850 0.9999939
1980-1989-1880-1889 19654.756 -67057.644 106367.157 0.9999843
1990-1999-1880-1889 57978.649 -25894.380 141851.679 0.5541450
2000-2009-1880-1889 71620.845 -11246.667 154488.356 0.1810156
2010-2019-1880-1889 224006.429 -8286.861 456299.718 0.0723775
1900-1909-1890-1899 -86488.267 -191449.538 18473.005 0.2481740
1910-1919-1890-1899 -84805.184 -177989.121 8378.753 0.1217183
1920-1929-1890-1899 -93048.316 -184459.179 -1637.453 0.0411921
1930-1939-1890-1899 -71900.833 -165407.766 21606.099 0.3622895
1940-1949-1890-1899 -89429.186 -181444.684 2586.313 0.0670378
1950-1959-1890-1899 -75380.996 -165668.964 14906.972 0.2285972
1960-1969-1890-1899 -62464.027 -152680.392 27752.339 0.5512831
1970-1979-1890-1899 -63488.332 -153601.240 26624.576 0.5200630
1980-1989-1890-1899 -26236.339 -119205.208 66732.530 0.9997775
1990-1999-1890-1899 12087.554 -78238.828 102413.936 1.0000000
2000-2009-1890-1899 25729.749 -63663.733 115123.232 0.9997201
2010-2019-1890-1899 178115.333 -56585.204 412815.871 0.3855093
1910-1919-1900-1909 1683.083 -61259.201 64625.366 1.0000000
1920-1929-1900-1909 -6560.049 -66846.290 53726.191 1.0000000
1930-1939-1900-1909 14587.433 -48832.054 78006.921 0.9999812
1940-1949-1900-1909 -2940.919 -64140.076 58258.238 1.0000000
1950-1959-1900-1909 11107.271 -47462.365 69676.906 0.9999984
1960-1969-1900-1909 24024.240 -34434.956 82483.436 0.9876943
1970-1979-1900-1909 22999.935 -35299.474 81299.344 0.9916837
1980-1989-1900-1909 60251.928 -2371.515 122875.371 0.0739911
1990-1999-1900-1909 98575.821 39946.987 157204.655 0.0000014
2000-2009-1900-1909 112218.016 55036.903 169399.129 0.0000000
2010-2019-1900-1909 264603.600 40186.962 489020.238 0.0057546
1920-1929-1910-1919 -8243.132 -44309.854 27823.590 0.9999826
1930-1939-1910-1919 12904.351 -28185.903 53994.604 0.9992436
1940-1949-1910-1919 -4624.002 -42196.791 32948.787 1.0000000
1950-1959-1910-1919 9424.188 -23693.478 42541.854 0.9997548
1960-1969-1910-1919 22341.157 -10580.799 55263.113 0.5866478
1970-1979-1910-1919 21316.852 -11320.530 53954.235 0.6511550
1980-1989-1910-1919 58568.845 18718.209 98419.481 0.0000675
1990-1999-1910-1919 96892.738 63670.489 130114.987 0.0000000
2000-2009-1910-1919 110534.933 79939.880 141129.987 0.0000000
2010-2019-1910-1919 262920.517 43764.853 482076.181 0.0043523
1930-1939-1920-1929 21147.483 -15745.725 58040.690 0.8285004
1940-1949-1920-1929 3619.130 -29311.315 36549.576 1.0000000
1950-1959-1920-1929 17667.320 -10072.175 45406.815 0.6909929
1960-1969-1920-1929 30584.289 3078.745 58089.834 0.0136999
1970-1979-1920-1929 29559.985 2395.696 56724.273 0.0183244
1980-1989-1920-1929 66811.977 31304.612 102319.343 0.0000000
1990-1999-1920-1929 105135.870 77271.599 133000.142 0.0000000
2000-2009-1920-1929 118778.066 94105.062 143451.069 0.0000000
2010-2019-1920-1929 271163.649 52755.992 489571.307 0.0024255
1940-1949-1930-1939 -17528.352 -55895.197 20838.492 0.9680902
1950-1959-1930-1939 -3480.163 -37496.043 30535.717 1.0000000
1960-1969-1930-1939 9436.807 -24388.561 43262.174 0.9998055
1970-1979-1930-1939 8412.502 -25135.957 41960.960 0.9999457
1980-1989-1930-1939 45664.495 5064.328 86264.661 0.0116699
1990-1999-1930-1939 83988.388 49870.677 118106.098 0.0000000
2000-2009-1930-1939 97630.583 66065.450 129195.716 0.0000000
2010-2019-1930-1939 250016.167 30722.972 469309.362 0.0095966
1950-1959-1940-1949 14048.190 -15623.103 43719.482 0.9569770
1960-1969-1940-1949 26965.159 -2487.532 56417.850 0.1157931
1970-1979-1940-1949 25940.854 -3193.396 55075.105 0.1450676
1980-1989-1940-1949 63192.847 26156.662 100229.032 0.0000009
1990-1999-1940-1949 101516.740 71728.762 131304.718 0.0000000
2000-2009-1940-1949 115158.935 88332.398 141985.472 0.0000000
2010-2019-1940-1949 267544.519 48883.112 486205.926 0.0031277
1960-1969-1950-1959 12916.969 -10588.909 36422.848 0.8692997
1970-1979-1950-1959 11892.664 -11212.960 34998.289 0.9174826
1980-1989-1950-1959 49144.657 16637.053 81652.261 0.0000326
1990-1999-1950-1959 87468.550 63543.899 111393.202 0.0000000
2000-2009-1950-1959 101110.745 80992.882 121228.609 0.0000000
2010-2019-1950-1959 253496.329 35556.255 471436.404 0.0071106
1970-1979-1960-1969 -1024.305 -23848.531 21799.921 1.0000000
1980-1989-1960-1969 36227.688 3919.489 68535.887 0.0121836
1990-1999-1960-1969 74551.581 50898.582 98204.580 0.0000000
2000-2009-1960-1969 88193.776 68399.741 107987.811 0.0000000
2010-2019-1960-1969 240579.360 22668.939 458489.781 0.0151069
1980-1989-1970-1979 37251.993 5233.822 69270.164 0.0070810
1990-1999-1970-1979 75575.886 52320.609 98831.163 0.0000000
2000-2009-1970-1979 89218.081 69901.058 108535.104 0.0000000
2010-2019-1970-1979 241603.665 23736.056 459471.274 0.0142167
1990-1999-1980-1989 38323.893 5709.749 70938.037 0.0060710
2000-2009-1980-1989 51966.088 22032.464 81899.712 0.0000005
2010-2019-1980-1989 204351.672 -14712.632 423415.977 0.0984998
2000-2009-1990-1999 13642.195 -6647.370 33931.761 0.6025918
2010-2019-1990-1999 166027.779 -51928.212 383983.770 0.3788597
2010-2019-2000-2009 152385.584 -65185.447 369956.615 0.5306953
$Location
diff lwr upr p adj
South-North -17988.131 -33571.23 -2405.029 0.0187573
West-North -12861.073 -21307.63 -4414.514 0.0010641
West-South 5127.058 -11045.87 21299.985 0.7374461
Conclusion:
Location Takeaway:
Houses build in the South tend to be roughly $18,000 cheaper than houses built in the North.
Housing build in the West tend to be roughly $13,0000 cheaper than houses built in the North.
There is no statistical evidence to support price difference from West to South houses.
Year Built Takeaways
2010 - 2019 houses are showing the largest price variation from other decades ranging anywhere from $150,000 - $200,000 more than older homes.
Houses built in the 2000-2009 decade tend to be $50,000 - $115,000 more expensive than houses built in most time frames in the 1990s.
There is also significant evidence to support houses built in the 1990-1999 decade are priced anywhere from $30,000 - $100,000 higher than older homes.