Introduction to R
  • Schedule
  • Syllabus
  • Instructors
  • Practice
  • Project
  • Resources

On this page

  • Questions
    • Question 1: Data Summarization: Intro
    • Question 2: Data Summarization: Quick summaries
    • Question 3: Data Summarization: Tables
    • Question 4: Data Summarization: Grouped summaries

Practice 6 Answers

PUBH 523/623

Author

Nicky Wakim

Modified

August 6, 2026

pacman::p_load(
  tidyverse, 
  rio, 
  here,
  skimr,
  janitor,
  rstatix,
  gtsummary,
  gt
)

1hrs_data <- import(here("data", "hrs_data.rds"))
1
This file path is specific to my folder set-up.

Questions

Question 1: Data Summarization: Intro

In Lesson 24, we saw that there are many ways to summarize data in R, and that the right tool often depends on whether a variable is categorical or numeric.

Part A: Categorical vs. numeric

WarningTask

In 1-2 sentences, explain why we might need different summary tools for categorical data versus numeric data. What does each type of tool tend to focus on?

Answer:

Not given

Part B: Sort the functions

WarningTask

For each function below, fill in the table with:

  1. Which package it comes from
  2. Whether it works on categorical, numeric, or both types of data
  3. What you’d use it for (a quick browse of a whole dataset, a custom/pointed summary, a grouped summary, or a presentation-ready table — more than one may apply)
  4. What it does, in your own words
Function Package Categorical, Numeric, or Both? What would you use it for? What does it do?
summary()
skim()
get_summary_stats()
summarise()
tabyl()
tbl_summary()

Answer:

Example of tabyl():

Function Package Categorical, Numeric, or Both? What would you use it for? What does it do?
summary()
skim()
get_summary_stats()
summarise()
tabyl() janitor Categorical A custom/pointed summary, a presentation-ready table Builds a frequency table (or cross-tabulation) of one or more categorical variables
tbl_summary()

Question 2: Data Summarization: Quick summaries

In Lesson 25, we covered three functions for quickly browsing a dataset: summary(), skim(), and get_summary_stats().

Part A: summary()

WarningTask 1

Use summary() on all of hrs_data. Look through the output but do not assign it to anything. Do you notice anything interesting about the summary statistics of HHID (our household identifier) and id (our observation identifier)?

Answer:

Here’s an example to show you the pattern — the rest of your answers should follow this same style, with code chunks and a #| ... chunk options as needed.

summary(hrs_data)
      HHID        pn               id          BIRTHYR        BIRTHMO      
 559839 :   8   010:1944   Length   :2728   Min.   :1922   Min.   : 1.000  
 559734 :   7   020: 784   N.unique :1717   1st Qu.:1958   1st Qu.: 3.750  
 554789 :   7              N.blank  :   0   Median :1967   Median : 7.000  
 555578 :   7              Min.nchar:  10   Mean   :1963   Mean   : 6.631  
 557721 :   7              Max.nchar:  10   3rd Qu.:1970   3rd Qu.:10.000  
 555053 :   6                               Max.   :1990   Max.   :12.000  
 (Other):2686                                                              
   BIRTHDATE               proxy                 coupled         sex      
 Min.   :-12314.0   Respondent:2721   Not a couple HH:1093   Female:1568  
 1st Qu.:  -480.8   Proxy     :   7   Couple HH      :1635   Male  :1160  
 Median :  2602.0                                                         
 Mean   :  1460.0                                                         
 3rd Qu.:  3757.0                                                         
 Max.   : 11215.0                                                         
                                                                          
     age_mo         age_yr             ed     
 Min.   : 382   Min.   : 34.00   Min.   : 0   
 1st Qu.: 635   1st Qu.: 52.00   1st Qu.:12   
 Median : 671   Median : 55.00   Median :13   
 Mean   : 711   Mean   : 58.82   Mean   :13   
 3rd Qu.: 778   3rd Qu.: 64.00   3rd Qu.:16   
 Max.   :1200   Max.   :100.00   Max.   :17   
                                 NAs    :507  
                                 degree                   race_original 
 High school diploma                :512   White/Caucasian       :1000  
 Master's degree                    :487   Black/African American: 884  
 Associate's degree                 :411   Other                 : 358  
 None                               :384   NAs                   : 486  
 Professional degree (Ph.D./M.D./JD):194                                
 (Other)                            :270                                
 NAs                                :470                                
 smoke_ever smoke_now  drink          height             srh     
 No :2267   No :1484   No : 854   Min.   :1.041   Fair     :743  
 Yes: 459   Yes:1243   Yes:1874   1st Qu.:1.626   Good     :870  
 NAs:   2   NAs:   1              Median :1.676   Very Good:647  
                                  Mean   :1.689   Excellent:277  
                                  3rd Qu.:1.765   Poor     :187  
                                  Max.   :2.083   NAs      :  4  
                                  NAs    :55                     
         act_vig       bp        diab      cancer      lung       hrt      
 Never       :1443   No :1287   No :1993   No :2457   No :2568   No :2355  
 >1 per week : 586   Yes:1433   Yes: 735   Yes: 271   Yes: 160   Yes: 373  
 1 per week  : 270   NAs:   8                                              
 1-3 per week: 275                                                         
 Every day   : 145                                                         
 NAs         :   9                                                         
                                                                           
  strk      psych      sleep       arth        cond_count         cesd      
 No :2535   No :2188   Yes: 534   No :1722   Min.   :0.000   Min.   :0.000  
 Yes: 193   Yes: 540   No :2194   Yes:1006   1st Qu.:1.000   1st Qu.:0.000  
                                             Median :2.000   Median :1.000  
                                             Mean   :1.733   Mean   :1.791  
                                             3rd Qu.:3.000   3rd Qu.:3.000  
                                             Max.   :7.000   Max.   :8.000  
                                                             NAs    :7      
     income       
 Min.   :      0  
 1st Qu.:  19852  
 Median :  51462  
 Mean   :  91813  
 3rd Qu.: 116500  
 Max.   :1800012  
                  
WarningTask 2

Now use summary() on just hrs_data$income. What is the median income?

TipTip

summary() treats categorical (factor) and numeric columns differently — categorical columns show counts per category, while numeric columns show min/median/mean/max, etc.

Answer:

Not given

Part B: skim()

WarningTask 1

Use skim() on all of hrs_data. What variables have missing categories from the top_counts?

Answer:

Not given

WarningTask 2

Using select(), first keep only cesd, cond_count, and income from hrs_data, then pipe the result into skim(). Based on the output, which of these three variables has the most missing values, and how many?

Answer:

Not given

Part C: get_summary_stats()

WarningTask 1

Use get_summary_stats() on hrs_data to get the "common" summary statistics for every numeric variable. Assign the result to hrs_01_summary_stats.

What is the IQR for ed?

Answer:

Start with something like:

hrs_01_summary_stats <- hrs_data |> 
  get_summary_stats(type = ______)
WarningTask 2

Now use get_summary_stats() again, but this time restrict it to just age_yr, cesd, and income, and set type = "mean_sd". Assign the result to hrs_02_summary_stats_meansd.

What is the standard deviation of cesd?

Answer:

Not given

TipTip

get_summary_stats() only works on numeric variables — any categorical variables you feed it will be silently dropped.

Question 3: Data Summarization: Tables

In Lesson 26, we covered two functions for building summary tables: tabyl() and tbl_summary(), plus gt() for presentation.

Part A: tabyl()

WarningTask 1

Use tabyl() to build a frequency table of srh (self-rated health). Assign the result to hrs_03_tabyl_srh.

Answer:

Example:

hrs_data |> 
  tabyl(srh)
       srh   n     percent valid_percent
      Fair 743 0.272360704    0.27276065
      Good 870 0.318914956    0.31938326
 Very Good 647 0.237170088    0.23751836
 Excellent 277 0.101539589    0.10168869
      Poor 187 0.068548387    0.06864905
      <NA>   4 0.001466276            NA
WarningTask 2

Use tabyl() to cross-tabulate srh by sleep. Assign the result to hrs_04_tabyl_cross.

Answer:

Not given

Part B: adorn_*()

WarningTask

Starting from hrs_04_tabyl_cross, add a totals row, convert the counts to column percentages, format the percentages to 1 decimal place, and add the raw counts back in front of the percentages. Assign the result to hrs_05_tabyl_formatted and display the table.

TipTip

Order matters when chaining adorn_*() functions together: tabulate → add totals → convert to percentages → format as percents → add counts back.

Answer:

Start with something like:

hrs_05_tabyl_formatted <- hrs_04_tabyl_cross |> 
  adorn_totals(______) |> 
  adorn_percentages(______) |> 
  adorn_pct_formatting(______) |> 
  adorn_ns(______)

Part C: tbl_summary()

WarningTask 1

Using select(), keep only age_yr, act_vig, bp, lung, cesd, and height from hrs_data, then pipe the result into tbl_summary(). Assign the result to hrs_06_tbl_summary.

  • How many missing values are there for “Ever Had High Blood Pressure”?
  • Do you notice any difference between the summary statistics for cesd using tbl_summary() and skim()?

Answer:

Not given

WarningTask 2

Starting over from hrs_data, build another tbl_summary() with just age_yr and height, but this time show {mean} ({sd}) for both variables instead of the defaults, and give height the display label "Self-Reported Height (m)" to make sure readers know height is measured in meters. Assign the result to hrs_07_tbl_summary_custom and display the table.

TipTip

Since both variables are numeric, we can use the following input to make ALL numeric variables show mean and standard deviation:

`statistic = all_continuous() ~ "{mean} ({sd})"`

Answer:

Start with something like:

hrs_07_tbl_summary_custom <- hrs_data |> 
  select(______) |> 
  tbl_summary(
    statistic = ______,
    label = height ~ ______
  )

Part D: gt()

WarningTask

Take hrs_03_tabyl_srh from Part A and pipe it into gt(), then use tab_header() to give the table the title "Self-Rated Health". Assign the result to hrs_08_gt.

Answer:

Not given

Question 4: Data Summarization: Grouped summaries

In Lesson 27, we covered how to compare summary statistics across groups using group_by() with summarise(), skim(), and get_summary_stats(), as well as the by = argument in tbl_summary().

Part A: summarise() with group_by()

WarningTask

Group hrs_data by degree, then use summarise() to calculate the mean and standard deviation of income for each group (remember to handle missing values). Assign the result to hrs_09_grouped_summarise.

Which degree group has the highest mean income?

Answer:

The resulting grouped summary would look something like this:

# A tibble: 8 × 3
  degree                              mean_income sd_income
  <fct>                                     <dbl>     <dbl>
1 High school diploma                      52925.    71746.
2 Master's degree                         140850.   159761.
3 Professional degree (Ph.D./M.D./JD)     183169.   182314.
4 None                                     38164.    53434.
5 Associate's degree                       72619.    84030.
6 GED                                      53784.    64956.
7 Bachelor's degree                        74178.    70370.
8 <NA>                                    121524.   166215.

Part B: skim() grouped

WarningTask

Group hrs_data by sex, use select() to keep only cesd and cond_count, and then pipe the result into skim(). Look through the output but do not assign it to anything.

Does the average cesd score differ between males and females?

Answer:

Not given

Part C: get_summary_stats() grouped

WarningTask

Group hrs_data by bp (high blood pressure), then use get_summary_stats() on age_yr and cond_count with type = "common". Assign the result to hrs_10_grouped_stats.

How does mean age_yr compare between those with and without high blood pressure?

Answer:

Not given

Part D: tbl_summary() with by =

WarningTask

Using select(), keep age_yr, cesd, srh, and diab from hrs_data, then use tbl_summary() to stratify the table by diabetes status. Assign the result to hrs_11_tbl_summary_grouped and display the table.

Answer:

Not given