{"id":894,"date":"2015-06-24T13:26:28","date_gmt":"2015-06-24T17:26:28","guid":{"rendered":"https:\/\/www.causeweb.org\/sbi\/?p=894"},"modified":"2015-06-24T18:33:06","modified_gmt":"2015-06-24T22:33:06","slug":"how-i-teach-sbi-using-r-2","status":"publish","type":"post","link":"https:\/\/www.causeweb.org\/sbi\/?p=894","title":{"rendered":"How I teach SBI using R"},"content":{"rendered":"<p><em><a href=\"https:\/\/www.causeweb.org\/sbi\/wp-content\/uploads\/2015\/06\/RPruim.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"  wp-image-892 alignleft\" src=\"https:\/\/www.causeweb.org\/sbi\/wp-content\/uploads\/2015\/06\/RPruim-225x300.jpg\" alt=\"RPruim\" width=\"154\" height=\"205\" srcset=\"https:\/\/www.causeweb.org\/sbi\/wp-content\/uploads\/2015\/06\/RPruim-225x300.jpg 225w, https:\/\/www.causeweb.org\/sbi\/wp-content\/uploads\/2015\/06\/RPruim-768x1024.jpg 768w, https:\/\/www.causeweb.org\/sbi\/wp-content\/uploads\/2015\/06\/RPruim-624x832.jpg 624w, https:\/\/www.causeweb.org\/sbi\/wp-content\/uploads\/2015\/06\/RPruim.jpg 900w\" sizes=\"auto, (max-width: 154px) 100vw, 154px\" \/><\/a><\/em><strong>R Pruim,\u00a0Calvin College<\/strong><\/p>\n<p>I\u2019m not writing to convince you that you <em>should<\/em> use <em>R<\/em> to teach simulation-based inference (SBI). My goal is to convince you that you <em>can<\/em> use <em>R<\/em> for SBI, even with students (and instructors) who have never used <em>R<\/em> before. Along the way I\u2019ll mention some guiding principles and illustrate some tools that my colleagues Danny Kaplan and Nick Horton and I have assembled in the <a href=\"https:\/\/github.com\/ProjectMOSAIC\/mosaic\/blob\/master\/README.md\"><code>mosaic<\/code> R package<\/a> to make SBI (and EDA and traditional inference procedures) much easier.[pullquote]The biggest key to using <em>R<\/em> well is to provide a lot of creative opportunity with as little <em>R<\/em> as possible.[\/pullquote]<\/p>\n<p><!--more--><\/p>\n<div class=\"container-fluid main-container\">\n<p>If you are unfamiliar with <em>R<\/em>, this post will be too short to give you a good introduction, but I hope it will make you curious enough to find out more. See the references for places to learn more about <em>R<\/em> and teaching with <em>R<\/em>.<\/p>\n<div id=\"less-volume-more-creativity\" class=\"section level3\">\n<h3>Less Volume, More Creativity<\/h3>\n<p>[pullquote]I find that using the <code>mosaic<\/code> package keeps the focus on what is important (thinking about where randomization enters and why, and what to do with the distribution once we have it) while hiding distracting details (looping structures, extracting the relevant information from <em>R<\/em> objects, etc.). [\/pullquote]The biggest key to using <em>R<\/em> well is to provide a lot of creative opportunity with as little <em>R<\/em> as possible. There can be a lot of ways to skin a cat in <em>R<\/em>, what you need is a systematic approach that allows you to economically achieve your goals. If technology is the most difficult thing in your course, then your technology is too hard or your questions are too simple (probably both). On the other hand, if your students are able to guess how to do new things in <em>R<\/em> before you show them, then you will know you are on the right track.<br \/>\n<!-- ### Doing randomization tests The R part of conducting hypothesis tests generally boils down to this: 1. Compute a test statistic from the data. Often this will involve a numerical summary function like `mean()` or a modeling function like `lm()`. The `mosaic` package gives all these (and graphical summaries, too) a common interface so that they can be learned as a single cognitive template. *perhaps insert template graphic here* 2. Figure out how to simulate a test statistic computed from random data assuming the null hypothesis is true. The main functions I use to introduce randomness are `rflip()` (for \"coin tosses\"), `shuffle()` (for rearranging the order), and `resample()` (for sampling with replacement). 3. Do that a lot of times. If we can do it once, then the `do()` function will let us do it lots of times. 4. Compare the test statistic from step 1 to the distribution in step 3. The same numerical and graphical summary functions used in step 1 can be used here because we make sure that the output from step 3 is a data frame, just like the original sample data was. Altogether, the R-related cognitive load for students is * [a template for graphical and numerical summaries](http:\/\/cran.r-project.org\/web\/packages\/mosaic\/vignettes\/LessVolume-MoreCreativity.html), which is needed for non SBI things as well * `rflip()`, `shuffle()` and `resample()` for generating random data * `do()` for repeating things These can be combined to perform a wide variety of tests.  That's a lot of creativity for little volume. In what follows, I will focus primarily on step 3, generating the randomization distribution since the other steps involve components that would need to be in place for any course using R to analyse data. --><\/p>\n<\/div>\n<div id=\"an-example-the-lady-tasting-tea\" class=\"section level3\">\n<h3>An example: The Lady Tasting Tea<\/h3>\n<p>I typically introduce inference on the first day doing a hypothesis test for a proportion \u201cinformally\u201d. I don\u2019t use terms like null hypothesis, or p-value, but all the big ideas are introduced.<\/p>\n<p>Often I use some variation on <a href=\"http:\/\/en.wikipedia.org\/wiki\/Lady_tasting_tea\">Fisher\u2019s Lady Tasting Tea<\/a> example because I find that students remember it well and I can refer back to it as a motivating example for the rest of the semester. I find the example works equally well in an Intro Stats course as in my upper level courses, and I like that it connects them in a small way to the history of the discipline.<\/p>\n<p>Let\u2019s see how we can test whether the lady is just guessing given that she correctly identifies 9 of 10 randomly prepared cups of tea. Guessing is like flipping a coin, so <code>mosaic<\/code> provides a coin flipper:<\/p>\n<pre class=\"r\"><code>require(mosaic)    # load the mosaic package\r\nrflip()            # think: random flip<\/code><\/pre>\n<pre><code>## \r\n## Flipping 1 coin [ Prob(Heads) = 0.5 ] ...\r\n## \r\n## H\r\n## \r\n## Number of Heads: 1 [Proportion Heads: 1]<\/code><\/pre>\n<p>Since our design calls for 10 cups of tea, we need to flip 10 coins. Fortunately, we don\u2019t have to use <code>rflip()<\/code> ten times and record the results manually. We just ask for 10 flips.<\/p>\n<pre class=\"r\"><code>rflip(n = 10)<\/code><\/pre>\n<pre><code>## \r\n## Flipping 10 coins [ Prob(Heads) = 0.5 ] ...\r\n## \r\n## H H H T T T H H H T\r\n## \r\n## Number of Heads: 6 [Proportion Heads: 0.6]<\/code><\/pre>\n<p>Now we need to do this a lot of times. The <code>do()<\/code> function provides an easy syntax and is clever about how it stores the results, in this case storing the number of flips, number of heads, number of tails, and proportion that are heads.<\/p>\n<pre class=\"r\"><code>do(1000) * rflip(n = 10)   # do 1000 times <\/code><\/pre>\n<pre><code>##    n heads tails prop\r\n## 1 10     6     4  0.6\r\n## 2 10     5     5  0.5\r\n## 3 10     4     6  0.4<\/code><\/pre>\n<pre><code>## &lt;997 lines omitted&gt;<\/code><\/pre>\n<p>Of course, we should look at this some other way than by having it all scroll past on our screen. Let\u2019s save the results and look at numerical and graphical summaries.<\/p>\n<pre class=\"r\"><code>GuessingLadies &lt;-\r\n  do(1000) * rflip(n = 10)  # simulate 1000 guessing ladies\r\ntally(~heads, data = GuessingLadies)<\/code><\/pre>\n<pre><code>## \r\n##   0   1   2   3   4   5   6   7   8   9  10 \r\n##   2   5  50 111 202 241 216 105  57  10   1<\/code><\/pre>\n<pre class=\"r\"><code>histogram(~heads, data = GuessingLadies, width = 1)<\/code><\/pre>\n<p>Based on our simulation, it appears that someone can get 9 or 10 just by guessing only about 1.1% of the time.<\/p>\n<p>If we want to have a more precise estimate of this proportion (the p-value), we can increase the number of times we <code>do()<\/code> things. We could also 999 (or 9999) instead of 1000 and include the observed statistic in the null distribution as recommended in the article Tim Hesterberg previews in <a href=\"https:\/\/www.causeweb.org\/sbi\/?p=521\">this SBI blog post<\/a>.<\/p>\n<\/div>\n<div id=\"grand-tour-of-randomization-distributions\" class=\"section level3\">\n<h3>Grand Tour of Randomization Distributions<\/h3>\n<p>If we want to test for a different proportion (e.g., 0.25), we simply tell <code>rflip()<\/code> the probability of obtaining heads (<code>p<\/code>) and the size of our sample (<code>n = 100<\/code> in the example below):<\/p>\n<pre class=\"r\"><code>Proportion.null &lt;- do(1000) * rflip(n = 100, p = 0.25) <\/code><\/pre>\n<pre><code>##     n heads tails prop\r\n## 1 100    31    69 0.31\r\n## 2 100    25    75 0.25<\/code><\/pre>\n<pre><code>&lt;998 rows omitted&gt;<\/code><\/pre>\n<p>Null distributions for permutation tests can be simulated by shuffling the appropriate labels. Here are examples for tests involving the difference between two proportions, the difference between two means, or a linear model:<\/p>\n<pre class=\"r\"><code>Galton2 &lt;- Galton %&gt;% group_by(family) %&gt;% sample_n(1)  # one from each family\r\nNull1 &lt;- do(1000) *  diffprop(  homeless ~ shuffle(sex),       data = HELPrct)\r\nNull2 &lt;- do(1000) *  diffmean(  height ~ shuffle(sex),       data = Galton2)\r\nNull3 &lt;- do(1000) *  lm(  age ~ shuffle(substance), data = HELPrct)  # ANOVA\r\nNull4 &lt;- do(1000) *  lm(  father ~ shuffle(mother),    data = Galton2)  # regression<\/code><\/pre>\n<p>Looking at the first few rows of <code>Null4<\/code>, we see that <code>do()<\/code> extracts and records several useful bits of information about a linear model:<\/p>\n<pre><code>##   Intercept  mother sigma r.squared     F\r\n## 1      79.8 -0.1641  2.60   0.02173 4.332\r\n## 2      74.1 -0.0736  2.62   0.00437 0.856\r\n## 3      63.9  0.0849  2.62   0.00582 1.141<\/code><\/pre>\n<p>We can use the slope (labeled <code>mother<\/code>), r<sup>2<\/sup>, or <em>F<\/em> as our test statistic.<\/p>\n<p>One null distribution that is somewhat more challenging is the null distribution for a test of a single mean. The challenge is to determine how to simulate data with a mean equal to that of the null hypothesis. This can be done non-parametrically by resampling from a shifted version of the empirical distribution. I find it simplest to do this by changing <em>H<\/em><sub>0<\/sub>: \u03bc = 98.6 into <em>H<\/em><sub>0<\/sub>: \u03bc &#8211; 98.6 = 0 and sampling with replacement from the sample:<\/p>\n<pre class=\"r\"><code>require(Lock5withR)\r\nNull &lt;- do(1000) * mean( ~ (BodyTemp - 98.6), data = resample(BodyTemp50))<\/code><\/pre>\n<p>Both the shifting and the introduction of sampling with replacement in the context of hypothesis testing may be more distracting than they are worth since a confidence interval for a mean is generally more useful anyway, but it rounds out our tour.<\/p>\n<\/div>\n<div id=\"bootstrap-too\" class=\"section level3\">\n<h3>Bootstrap, too<\/h3>\n<p>Generating bootstrap distributions to form confidence intervals is similar. Typically, instead of shuffling a variable we resample the entire data set (possibly within groups) to produce a bootstrap distribution. Here is a bootstrap distribution for the difference in mean heights of men and women using Galton\u2019s data, resampling separately from the males and females:<\/p>\n<pre class=\"r\"><code>HeightBySex.boot &lt;- \r\n  do(1000) * diffmean( height ~ sex, data = resample(Galton, groups = sex) )\r\nhistogram(~diffmean, data = HeightBySex.boot)<\/code><\/pre>\n<p>Simple confidence intervals can be computed using percentiles<\/p>\n<pre class=\"r\"><code>cdata(0.95, ~diffmean, data = HeightBySex.boot)  # central 95%<\/code><\/pre>\n<pre><code>##       low        hi central.p \r\n##      4.78      5.46      0.95<\/code><\/pre>\n<p>or the bootstrap standard error, which is just the standard deviation of the bootstrap distribution.<\/p>\n<pre class=\"r\"><code>sd(~diffmean, data=HeightBySex.boot)<\/code><\/pre>\n<pre><code>## [1] 0.166<\/code><\/pre>\n<p>Eventually, I may show my students how to automate generating the confidence intervals from the boostrap distribution.<\/p>\n<pre class=\"r\"><code>confint(HeightBySex.boot, method=c(\"percentile\", \"se\"))<\/code><\/pre>\n<pre><code>##       name lower upper level   method estimate margin.of.error  df\r\n## 1 diffmean  4.78  5.46  0.95 quantile       NA              NA  NA\r\n## 2 diffmean  4.80  5.45  0.95   stderr     5.12           0.326 897<\/code><\/pre>\n<\/div>\n<div id=\"striking-a-balance\" class=\"section level3\">\n<h3>Striking a Balance<\/h3>\n<p>I find that using the <code>mosaic<\/code> package keeps the focus on what is important (thinking about where randomization enters and why, and what to do with the distribution once we have it) while hiding distracting details (looping structures, extracting the relevant information from <em>R<\/em> objects, etc.). There are other <em>R<\/em> packages (<a href=\"http:\/\/cran.r-project.org\/web\/packages\/resample\/index.html\"><code>resample<\/code><\/a> and <a href=\"http:\/\/cran.r-project.org\/web\/packages\/boot\/index.html\"><code>boot<\/code><\/a>, for example) that are faster and use more sophisticated methods, but hide some of the things I want students to see and think about when they are learning how simulation-based inference works.<\/p>\n<p>The <em>R<\/em>-related cognitive load for students to do SBI using <code>mosaic<\/code> amounts to<\/p>\n<ul>\n<li><a href=\"http:\/\/cran.r-project.org\/web\/packages\/mosaic\/vignettes\/LessVolume-MoreCreativity.html\">a common template for graphical and numerical summaries<\/a>, which is needed for non-SBI things as well<\/li>\n<\/ul>\n<p><center><br \/>\n<strong><span class=\"boxed\">goal<\/span> ( <span class=\"boxed\">\u00a0y\u00a0<\/span> ~ <span class=\"boxed\">\u00a0x\u00a0<\/span> , data = <span class=\"boxed\">mydata<\/span> )<\/strong><\/center><\/p>\n<ul>\n<li><code>rflip()<\/code>, <code>shuffle()<\/code> and <code>resample()<\/code> for generating random data<\/li>\n<li><code>do()<\/code> for repeating things<\/li>\n<\/ul>\n<p>These can be combined to handle a wide variety of situations. That\u2019s a lot of SBI creativity for little volume.<\/p>\n<\/div>\n<div id=\"additional-resources\" class=\"section level3\">\n<h3>Additional Resources<\/h3>\n<p>The following resources are provided by Project MOSAIC (Danny Kaplan, Nick Horton, and Randy Pruim) for those interested in learning more about using <em>R<\/em> to teach statistics.<\/p>\n<ul>\n<li><a href=\"https:\/\/www.causeweb.org\/ecots\/ecots14\/45\/\">eCOTS 2014 Workshop: \u201cEffective Teaching using R, RStudio, and the MOSAIC Package\u201d<\/a>.<\/li>\n<li><a href=\"http:\/\/cran.r-project.org\/web\/packages\/mosaic\/vignettes\/LessVolume-MoreCreativity.html\"><em>Less Volume, More Creativity<\/em><\/a> \u2013 an introduction to the <code>mosaic<\/code> package emphasizing the use of a common template for numerical summaries, graphical summaries, and modeling.<\/li>\n<li><em>Randomization based Inference<\/em> <a href=\"https:\/\/github.com\/ProjectMOSAIC\/mosaic\/blob\/master\/vignettes\/Resampling.pdf\">[view]<\/a> <a href=\"https:\/\/github.com\/ProjectMOSAIC\/mosaic\/raw\/master\/vignettes\/Resampling.pdf\">[download]<\/a> \u2013 examples of simulation-based inference with <code>mosaic<\/code> based on the 2013 USCOTS Randomization Bake Off<\/li>\n<li><em><a href=\"http:\/\/mosaic-web.org\/go\/Master-Starting.pdf\" target=\"_blank\">Start Teaching with\u00a0R<\/a><\/em><\/li>\n<li><em><a href=\"http:\/\/cran.r-project.org\/doc\/contrib\/Horton+Pruim+Kaplan_MOSAIC-StudentGuide.pdf\" target=\"_blank\">A Student\u2019s Guide to R<\/a><\/em><\/li>\n<li><a href=\"https:\/\/github.com\/rpruim\/Lock5withR\/blob\/master\/README.md\">Lock5withR<\/a> \u2013 a companion to <em>Unlocking the Power of Data<\/em> by Five Locks (with Lana Park)<\/li>\n<li><a href=\"https:\/\/github.com\/rpruim\/ISIwithR\/blob\/master\/README.md\">ISIwithR<\/a> \u2013 a companion to <em>Introduction to Statistical Inference<\/em> by Nathan Tintle <em>et al.<\/em> (with Lana Park)<\/li>\n<\/ul>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>R Pruim,\u00a0Calvin College I\u2019m not writing to convince you that you should use R to teach simulation-based inference (SBI). My goal is to convince you that you can use R for SBI, even with students (and instructors) who have never used R before. Along the way I\u2019ll mention some guiding principles and illustrate some tools [&hellip;]<\/p>\n","protected":false},"author":36,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-894","post","type-post","status-publish","format-standard","hentry","category-how-do-you-use-technology"],"_links":{"self":[{"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=\/wp\/v2\/posts\/894","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=\/wp\/v2\/users\/36"}],"replies":[{"embeddable":true,"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=894"}],"version-history":[{"count":18,"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=\/wp\/v2\/posts\/894\/revisions"}],"predecessor-version":[{"id":914,"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=\/wp\/v2\/posts\/894\/revisions\/914"}],"wp:attachment":[{"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.causeweb.org\/sbi\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}