Last updated on 2017-05-15
ggplot2
?join
So far we've seen simple linear regression
In Lec 36 LC we saw the relationship between \(x =\) dep delay & \(y =\) arr delay for Alaska Airlines flights.
carrier
doesn't vary.carrier == F9
)So we have:
Is there a difference in delays between Alaska and Frontier?
Is there a difference in delays between Alaska and Frontier?
What does "best fitting line"" mean?
Consider ANY point (in blue).
Now consider this point's deviation from the regression line.
Do this for another point…
Do this for another point…
Regression line minimizes the sum of squared arrow lengths.
n=100
Here are your 12 resulting \(\widehat{p}\)'s…
p_hat | |
---|---|
aghall | 0.360 |
ccrobinson | 0.402 |
chimstead | 0.380 |
cwhitedzuro | 0.440 |
dmortime | 0.430 |
efeldman | 0.370 |
jobrien | 0.400 |
jvolz | 0.420 |
lschroer | 0.402 |
rlightman | 0.400 |
rstoreyfisher | 0.390 |
zmillslagle | 0.402 |
Let me add 8 of my own so we have 20…
p_hat | |
---|---|
aghall | 0.360 |
ccrobinson | 0.402 |
chimstead | 0.380 |
cwhitedzuro | 0.440 |
dmortime | 0.430 |
efeldman | 0.370 |
jobrien | 0.400 |
jvolz | 0.420 |
lschroer | 0.402 |
rlightman | 0.400 |
rstoreyfisher | 0.390 |
zmillslagle | 0.402 |
aykim | 0.420 |
aykim | 0.360 |
aykim | 0.300 |
aykim | 0.360 |
aykim | 0.360 |
aykim | 0.400 |
aykim | 0.340 |
aykim | 0.400 |
Let's compute \(\mbox{SE} = \sqrt{\frac{\widehat{p}(1-\widehat{p})}{n}}\)…
p_hat <- p_hat %>% mutate( n = 100, SE = sqrt(p_hat*(1-p_hat)/n) )
p_hat | n | SE | |
---|---|---|---|
aghall | 0.360 | 100 | 0.048 |
ccrobinson | 0.402 | 100 | 0.049 |
chimstead | 0.380 | 100 | 0.049 |
cwhitedzuro | 0.440 | 100 | 0.050 |
dmortime | 0.430 | 100 | 0.050 |
efeldman | 0.370 | 100 | 0.048 |
jobrien | 0.400 | 100 | 0.049 |
jvolz | 0.420 | 100 | 0.049 |
lschroer | 0.402 | 100 | 0.049 |
rlightman | 0.400 | 100 | 0.049 |
rstoreyfisher | 0.390 | 100 | 0.049 |
zmillslagle | 0.402 | 100 | 0.049 |
aykim | 0.420 | 100 | 0.049 |
aykim | 0.360 | 100 | 0.048 |
aykim | 0.300 | 100 | 0.046 |
aykim | 0.360 | 100 | 0.048 |
aykim | 0.360 | 100 | 0.048 |
aykim | 0.400 | 100 | 0.049 |
aykim | 0.340 | 100 | 0.047 |
aykim | 0.400 | 100 | 0.049 |
Finally the left and right end points of the 95% confidence interval. Whose CI's captured the true \(p=0.4023\)?
p_hat <- p_hat %>% mutate( left = p_hat - 1.96*SE, right = p_hat + 1.96*SE )
p_hat | n | SE | left | right | |
---|---|---|---|---|---|
aghall | 0.360 | 100 | 0.048 | 0.266 | 0.454 |
ccrobinson | 0.402 | 100 | 0.049 | 0.306 | 0.498 |
chimstead | 0.380 | 100 | 0.049 | 0.285 | 0.475 |
cwhitedzuro | 0.440 | 100 | 0.050 | 0.343 | 0.537 |
dmortime | 0.430 | 100 | 0.050 | 0.333 | 0.527 |
efeldman | 0.370 | 100 | 0.048 | 0.275 | 0.465 |
jobrien | 0.400 | 100 | 0.049 | 0.304 | 0.496 |
jvolz | 0.420 | 100 | 0.049 | 0.323 | 0.517 |
lschroer | 0.402 | 100 | 0.049 | 0.306 | 0.498 |
rlightman | 0.400 | 100 | 0.049 | 0.304 | 0.496 |
rstoreyfisher | 0.390 | 100 | 0.049 | 0.294 | 0.486 |
zmillslagle | 0.402 | 100 | 0.049 | 0.306 | 0.498 |
aykim | 0.420 | 100 | 0.049 | 0.323 | 0.517 |
aykim | 0.360 | 100 | 0.048 | 0.266 | 0.454 |
aykim | 0.300 | 100 | 0.046 | 0.210 | 0.390 |
aykim | 0.360 | 100 | 0.048 | 0.266 | 0.454 |
aykim | 0.360 | 100 | 0.048 | 0.266 | 0.454 |
aykim | 0.400 | 100 | 0.049 | 0.304 | 0.496 |
aykim | 0.340 | 100 | 0.047 | 0.247 | 0.433 |
aykim | 0.400 | 100 | 0.049 | 0.304 | 0.496 |
Recall the nycflights
data set. For Alaska Air flights, let's explore the relationship between
The correlation coefficient is computed as follows:
cor(alaska_flights$dep_delay, alaska_flights$arr_delay)
## [1] 0.8373792
83.7% is fairly strongly positively associated!
Chalk talk
For large \(n\), the sampling distribution for these point estimates are bell-shaped, thus a 95% C.I. is \(\mbox{PE} \pm 1.96\times \mbox{SE}\).
Population Parameter | Sample Statistic |
---|---|
Mean \(\mu\) | Sample Mean \(\overline{x}\) |
Proportion \(p\) | Sample Proportion \(\widehat{p}\) |
Diff of Means \(\mu_1 - \mu_2\) | \(\overline{x}_1 - \overline{x}_2\) |
Diff of Proportions \(p_1 - p_2\) | \(\widehat{p}_1 - \widehat{p}_2\) |
NPR report on Obama from 2013. Chalk talk…
We are estimating a population parameter using a point estimate based on a sample. Example: Mean (Chalk Talk)
Imagine the \(\mu\) is a fish:
Point Estimate \(\overline{x}\) | Confidence Interval |
---|---|
Age example:
n=3
studentsNote:
From the OkCupid population:
n
Taking a sample in order to infer about a population:
Let's Google "define infer"…
library(lubridate) library(mosaic) library(dplyr) # Randomly sample three people: students <- c("Arthur", "Caroline", "Claire", "Clare", "Conor", "Daniel", "Dylan", "Elana", "Jacob", "Jay", "Joe", "Julian", "Kelsie", "Lisa", "Maya", "Naing", "Parker", "Rebecca", "Ry", "Theodora", "Zebediah", "Albert") resample(students, size=3, replace=FALSE) # Get average age: birthdays <- c("1980-11-05", "2000-01-01", "1955-08-05") ages <- as.numeric(as.Date("2017-04-27") - as.Date(birthdays))/365.25 ages mean(ages)
Questions:
Chalk talk…
If we assume \(H_0\) is true (there is no difference in test scores between evens and odds) then:
even_vs_odd
is irrelevantfinal | even_vs_odd |
---|---|
0.94 | even |
0.88 | odd |
0.84 | even |
0.84 | odd |
0.77 | even |
final | even_vs_odd |
---|---|
0.94 | even |
0.88 | odd |
0.84 | even |
0.84 | even |
0.77 | odd |
final | even_vs_odd |
---|---|
0.94 | even |
0.88 | even |
0.84 | odd |
0.84 | even |
0.77 | odd |
final | even_vs_odd |
---|---|
0.94 | even |
0.88 | even |
0.84 | odd |
0.84 | odd |
0.77 | even |
From last lecture: How do we construct null distribution?
In this case, the null distribution is barplot:
Analytically | Via Simulation |
---|---|
Only chalk talk today, based on Learning Checks for Lec26.
Not very! Only occurs 0.34% of the time
p-value: Chalk Talk
If guessing at random, here are hypothetical outcomes:
She got 8/8 right!
Critical chalk talk.
ggplot2
?join
Binary situations, like
are often coded as 1
vs 0
in many programming languages.
Ezell's Fried Chicken is a famous chicken restaurant in Seattle. Oprah Winfrey has it flown into to Chicago.
One day I was raving about Ezell's Chicken, but my friend accused me of "buying into the hype".
So what did we do?
Fried Chicken Face Off:
Do people prefer this? | Or this? |
---|---|
How would you design a taste test to ascertain, independent of hype, which fried chicken tastes better?
Use the relevant principles of designing experiements from above.
The mosaic
package has functions for the random simulation.
rflip()
: Flip a coinshuffle()
: Shuffle a set of valuesdo()
: Do the same thing many, many, many timesresample()
: the swiss army knife for samplingRun the following in your console:
library(mosaic) # Define a vector fruit fruit <- c("apple", "orange", "mango") # Do this multiple times: shuffle(fruit)
Two types of sampling:
resample()
by default samples with replacement. Run this in the console multiple times:
resample(fruit)
resample()
Chalk Talk
Chalk Talk 1
There are two approaches to studying probability:
Mathematically (MATH 310) | Via Simulations |
---|---|
Doing this repeatedly by hand is tiring:
All hail the mosaic
package: library(mosaic)
.
Chalk Talk 2
Best viewed in HTML mode, not slide deck mode:
You should draw out what your end data frame should look like in tidy format:
Why? If you don't clearly identify this, not only will your work not be focused, but more importantly, how would you know when you're done?
Before starting any substantive data wrangling using mutate
, summarise
, arrange
, or _join
, I like to pare down the necessary data sets to the minimum of what I need by
filter
only the absolutely necessary rowsselect
only the absolutely neccesary columnsWhy? This has several benefits:
View()
s of your work as you progress.nycflights13
data sets: flights
, planes
, airlines
, weather
, and airports
.Why? If you confuse the what and the how, you'll only get doubly lost. Separate them out!
Done with "Tidy" and "Transform", start with "Model":
Growing up I used to only eat white rice, but now I only eat multigrain rice.
White Rice | Multigrain Rice |
---|---|
What is my spin on multigrain rice made of?
Chalk Talk
For each of the following 4 scenarios
1: Identify
2: Comment on the representativeness/generalizability of the results of the sample to the population.
.xlsx
files are clunky as they have lots of Microsoft metadata we don't need. Can use readxl
package to load Excel files.csv
files are a minimalist spreadsheet format.A .csv
file (example) is just data and no fluff:
Today you will load DD_vs_SB.csv
file that contains the Dunkin Donuts and Starbucks data. Delaney Moran scraped the web for the following data: For each of 1024 census tracts in Eastern Massachusetts:
View()
panel should pop up with the data. Make sure that the variable names are correct.We add regression lines…
After loading DD_vs_SB.csv
:
library(ggplot2) ggplot(DD_vs_SB, aes(x=median_income, y=shops_per_1000)) + geom_point(aes(col=Type)) + facet_wrap(~Type) + geom_smooth(method="lm", se=FALSE) + labs(x="Median Household Income", y="# of shops per 1000 people", title="Coffee/Cafe Comparison in Eastern MA") + scale_color_manual(values=c("orange", "forestgreen"))
arrange()
& _join
filter()
rows/observations matching criteriasummarize()
numerical variablesgroup_by()
group rows/observations by a categorical variablemutate()
existing variables to create new onesarrange()
rowsAnd _join
!
Really simple. Either
DATASET_NAME %>% arrange(VARIABLE_NAME)
orDATASET_NAME %>% arrange(desc(VARIABLE_NAME))
library(dplyr) # Create data frame with two variables test_data <- data_frame( name=c("Abbi", "Abbi", "Ilana", "Ilana", "Ilana"), value_1=c(0, 1, 0, 1, 0), value_2=c(4, 6, 3, 2, 5) ) # See contents in console test_data
Run this code. Notice the subtle diff between 2 and 3:
# 1: Arrange in ascending order test_data %>% arrange(value_1) # 2: Arrange in descending order test_data %>% arrange(desc(value_1)) # 3: Arrange in decending order of value_1, and then within # value_1, arrange in ascending order of value_2 test_data %>% arrange(desc(value_1), value_2)
And now the last component of data wrangling: joining/merging two data sets. Run the following:
x <- data_frame(x1=c("A","B","C"), x2=c(1,2,3)) y <- data_frame(x1=c("A","B","D"), x3=c(TRUE,FALSE,TRUE)) x y
We join by the "x1"
variable. Note how it is in quotation marks.
left_join(x, y, by = "x1") full_join(x, y, by = "x1")
join
(right-hand column of back of cheatsheet). To keep things simple, we'll try to only use:
left_join
full_join
group_by()
& 5MV#4 mutate()
filter()
rows/observations matching criteriasummarize()
numerical variablesgroup_by()
group rows/observations by a categorical variablemutate()
existing variables to create new onesarrange()
rowsRun the following in your console:
library(dplyr) # Create data frame with two variables test_data <- data_frame( name=c("Albert", "Albert", "Albert", "Yolanda", "Yolanda"), value=c(2, 2, 2, 3, 3) ) # See contents in console test_data
group_by(name)
puts grouping meta-dataRun the following. Notice the data itself doesn't change, but the data about the data does:
test_data test_data %>% group_by(name)
Run both these
test_data %>% summarise(overall_avg = mean(value)) test_data %>% group_by(name) %>% summarise(name_avg = mean(value))
What's the difference?
Chalk talk
Here:
Mutate existing variables to create new ones. Always of the form:
DATASET_NAME %>% mutate(NEW_VARIABLE_NAME = OLD_VARIABLE_NAMES)
Using the same example as earlier. Run both:
test_data %>% mutate(double_value = value * 2) test_data %>% mutate(double_value = value * 2) %>% mutate(triple_value = value + double_value)
%>%
, 5MV#1 filter
ing, and 5MV#2 summarize()
%>%
Piping allows you to
filter()
rows/observations matching criteriasummarize()
numerical variablesgroup_by()
group rows/observations by a categorical variablemutate()
existing variables to create new onesarrange()
rowsfilter()
rows/observations matching criteria
Take flights
and then filter for all rows where year
is equal to 2014.
Note we use ==
and not =
library(dplyr) library(nycflights13) data(flights) flights %>% filter(year == 2014)
summarize()
numerical variables using a many to one function:
Examples of many to one functions:
sum()
: sum of n valuesmean()
: mean of n valuessd()
: standard deviation of n valuesWhat's going here?
library(dplyr) library(nycflights13) data(weather) weather %>% summarize(mean_temp = mean(temp))
With the internet, we are in a new age of data:
Jenny Bryan said: "Classroom data are like teddy bears and real data are like a grizzly bear with salmon blood dripping out its mouth."
Traditional Classroom Data | Real Data |
---|---|
Some attributes of real data:
Inconsistent formatting is a real pain:
To take this, we now officially introduce the dplyr
package: a grammar of data manipulation
function()
you use.Say hello to the 5MV: the five main verbs
filter()
rows/observations matching criteriasummarize()
numerical variablesgroup_by()
group rows/observations by a categorical variablemutate()
existing variables to create new onesarrange()
rowsAlso, later _join()
two separate data frames by
corresponding variables
Recall from first Grammar of Graphics lecture, we displayed
Say these piecharts represent polls for a local election with 5 candidates at time points A, B, and C:
Answer the following questions:
geom_bar()
is the trickiest of the 5NG, so we'll use it in limited capacity.Two different ways to have counts show on y-axis:
geom_bar()
data
in a variable count
, n
, etc.Counts are not pre-computed:
Row Number | name |
---|---|
1 | Albert |
2 | Albert |
3 | Albert |
4 | Mo |
5 | Mo |
Counts are pre-computed in variable n
. So n
becomes a y
aesthetic variable!
5
ggplot2
?If I know your name, I can guess your age. Looking at the handout answer the following questions:
As of Jan 1st, 2014 in the United States
Chalk Talk: Age of 544 Members of 113th United States Congress:
From okcupiddata
package, the profiles
data set:
Restricted to heights between 55 (5'5'') and 80 (6'8'') inches:
x
aestheticy
aestheticFor values: \(-2.5, -1.5, -0.5, 0.5, 1.5, 2.5\)
Let's draw histograms using the following binning structures:
Facets allow you split ANY plot by a categorical variable. In this case by adding +facet_wrap(~sex)
to the ggplot()
call
A | B | C | D |
---|---|---|---|
1 | 1 | 3 | Hot |
2 | 2 | 2 | Hot |
3 | 3 | 1 | Cold |
4 | 4 | 2 | Cold |
A statistical graphic is a mapping of data
variables to aes()
thetic attributes of geom_
etric objects.
ggplot(data=simple_ex, aes(x=A, y=B, size=C, color=D )) + geom_line()
What's not great about this plot, especially near (0, 0)?
This is called overplotting: when points are stacked so densely we can't see what's going on!
There are two ways of dealing with this:
A statistical graphic is a mapping of data
variables to aes()
thetic attributes of geom_
etric objects.
The five named graphs we'll see in this class. Note: I reordered them from last time to be easiest to hardest to work with:
ggplot2
packageIn tidy format:
A | B | C | D |
---|---|---|---|
1 | 1 | 3 | Hot |
2 | 2 | 2 | Hot |
3 | 3 | 1 | Cold |
4 | 4 | 2 | Cold |
In 1812, Napoleon led a French invasion of Russia, marching on Moscow.
It was one of the biggest military disasters ever, in particular b/c of the Russian winter.
Famous graphical illustration of Napolean's march to/from Moscow
This was considered a revolution in statistical graphics because between
there are 6 dimensions of information (i.e. variables) being displayed on a 2D page.
A statistical graphic is a mapping of data
variables to aes()
thetic attributes of geom_
etric objects.
Where? | data |
aes() |
geom_ |
---|---|---|---|
top map | longitude | x |
point |
" | latitude | y |
point |
" | army size | size |
path |
" | army direction (forward vs retreat) | color |
path |
bottom graph | date | x |
line & text |
" | temperature | y |
line & text |
2005 - Proposal | 2009 - R Implementtation |
---|---|
From ggplot2movies
package, the movies
data set:
From nycflights13
package, the flights
data set:
From okcupiddata
package, the profiles
data set:
From fueleconomy
package, the vehicles
data set:
From babynames
package, the babynames
data set:
Say hello to the 5NG: the five named graphs
The nycflights13
package contains "tidy data" all 336,776 flights that departed from NYC (e.g. EWR, JFK and LGA) in 2013.
To help understand what causes delays, it also includes a number of other useful datasets.
weather
: hourly meterological data for each airportplanes
: construction information about each planeairports
: airport names and locationsairlines
: translation between two letter carrier codes and namesIn small teams, take 3 minutes to write down
Recall the tradeoff:
Less of this… | More of this… |
---|---|
You need to install each package once.
You need to load a package everytime you want to use it.
library(PACKAGENAME)
in the console.Today's Learning Check: Install and then load 3 packages:
dplyr
: a package for data manipulationggplot2
: a package for data visualizationbabynames
: a package of baby name datababynames
PackageThe babynames
package contains for each year from 1880 to 2013, the number of children born of each sex given each name in the United States. Only names with more than 5 occurrences are considered.
Have students engage in the data/science research pipeline in as faithful a manner as possible while maintaining a level suitable for novices.
We will, as best we can, perform all this:
And not just this, as in many previous intro stats courses:
Foster a conceptual understanding of statistical topics and methods using simulation/resampling and real data whenever possible, rather than mathematical formulae.
In this course, computers and not math will be the "engine". What does this mean?
Blur the traditional lecture/lab dichotomy of introductory statistics courses by incorporating more computational and algorithmic thinking into the syllabus.
go/rstudio/
(on campus or via VPN)Develop statistical literacy by, among other ways, tying in the curriculum to current events, demonstrating the importance statistics plays in society.
Either
R | RStudio | DataCamp |
---|---|---|
go/rstudio/
with your Midd accountNow we will use R via DataCamp instead of via RStudio, but just for driver's ed. Two panels exist in both: