Predicting Maximum Heart Rate

Cross-Sectional Analysis of Heart Health Data

Author

Jack Herman, Grant Dobbs, and Jeremiah Brooks.

Introduction

Heart health can be influenced by many different factors, including age, blood pressure, cholesterol, and a person’s response to exercise. Understanding the relationships between these characteristics can help us better understand cardiovascular health.

For this project, we analyze a cross-sectional heart health dataset. Each observation represents a patient, and the dataset contains both quantitative and qualitative variables related to cardiovascular health.

Our main research question is:

What factors are associated with a patient’s maximum heart rate during exercise?

Our dependent variable, or Y variable, is thalach, which represents the maximum heart rate achieved by a patient.

Maximum heart rate is useful to study because it reflects how a patient’s cardiovascular system responds during exercise. Understanding which patient characteristics are associated with maximum heart rate can help us better describe differences in exercise response across patients.

We will investigate whether characteristics such as age, heart disease status, sex, chest pain type, exercise-induced angina, and ST depression can help explain differences in maximum heart rate.

Setup

First, we load the packages that will be used throughout our analysis.

The tidyverse package is used for data cleaning and visualization. The knitr package is used to create cleaner tables, and stargazer is used to present the three regression specifications together in a professional regression table.

Importing the Data

We begin by importing the original heart.csv file.

We can view the first six observations to make sure the dataset imported correctly.

  age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal
1  52   1  0      125  212   0       1     168     0     1.0     2  2    3
2  53   1  0      140  203   1       0     155     1     3.1     0  0    3
3  70   1  0      145  174   0       1     125     1     2.6     0  0    3
4  61   1  0      148  203   0       1     161     0     0.0     2  1    3
5  62   0  0      138  294   1       1     106     0     1.9     1  3    2
6  58   0  0      100  248   0       0     122     0     1.0     1  0    2
  target
1      0
2      0
3      0
4      0
5      0
6      1

Next, we check the dimensions of the dataset.

[1] 1025   14

The first number represents the number of observations, while the second number represents the number of variables.

Understanding the Data

We can examine the structure of the original dataset using str().

'data.frame':   1025 obs. of  14 variables:
 $ age     : int  52 53 70 61 62 58 58 55 46 54 ...
 $ sex     : int  1 1 1 1 0 0 1 1 1 1 ...
 $ cp      : int  0 0 0 0 0 0 0 0 0 0 ...
 $ trestbps: int  125 140 145 148 138 100 114 160 120 122 ...
 $ chol    : int  212 203 174 203 294 248 318 289 249 286 ...
 $ fbs     : int  0 1 0 0 1 0 0 0 0 0 ...
 $ restecg : int  1 0 1 1 1 0 2 0 0 0 ...
 $ thalach : int  168 155 125 161 106 122 140 145 144 116 ...
 $ exang   : int  0 1 1 0 0 0 0 1 0 1 ...
 $ oldpeak : num  1 3.1 2.6 0 1.9 1 4.4 0.8 0.8 3.2 ...
 $ slope   : int  2 0 0 2 1 1 0 1 2 1 ...
 $ ca      : int  2 0 0 1 3 0 3 1 0 2 ...
 $ thal    : int  3 3 3 3 2 2 1 3 3 2 ...
 $ target  : int  0 0 0 0 0 1 0 0 0 0 ...

The dataset contains the following variables:

  • age: Age of the patient in years
  • sex: Sex
  • cp: Chest pain type
  • trestbps: Resting blood pressure
  • chol: Serum cholesterol
  • fbs: Fasting blood sugar category
  • restecg: Resting ECG result
  • thalach: Maximum heart rate achieved
  • exang: Exercise-induced angina
  • oldpeak: ST depression induced by exercise
  • slope: Slope of the peak exercise ST segment
  • ca: Number of major vessels
  • thal: Thalassemia category
  • target: Heart disease status

Quantitative Variables

Our dataset contains several quantitative variables, including:

  1. age — age in years
  2. trestbps — resting blood pressure
  3. chol — cholesterol
  4. thalach — maximum heart rate
  5. oldpeak — ST depression

This gives us at least four quantitative variables as required by the project.

Qualitative Variables

Several variables are represented by numbers in the raw dataset but actually represent categories.

These include:

  1. sex
  2. cp
  3. fbs
  4. restecg
  5. exang
  6. slope
  7. thal
  8. target

This gives us at least four qualitative variables as required by the project.

Data Source, Unit of Observation, and Measurement Levels

Data Source

The raw file used in this project is heart.csv.

Before submitting, replace this sentence with the exact source from which your group obtained the file (for example, the course page, Kaggle page, or another repository) and include the source citation/link in the Appendix. The source is not stated in the materials currently available, so it should not be guessed.

Unit of Observation

The unit of observation is one patient. Each row contains characteristics and heart-health measurements for an individual patient.

Variable Types and Levels of Measurement

The table below identifies the major variables, whether they are quantitative or qualitative, and how they are treated in this analysis.

Major Variables and Measurement Levels
Variable Description Type Measurement Level
age Age in years Quantitative Ratio
trestbps Resting blood pressure Quantitative Ratio
chol Serum cholesterol Quantitative Ratio
thalach Maximum heart rate achieved Quantitative Ratio
oldpeak ST depression induced by exercise Quantitative Continuous
sex Sex category Qualitative Nominal
cp Chest pain type Qualitative Nominal
fbs Fasting blood sugar category Qualitative Nominal
restecg Resting ECG category Qualitative Nominal
exang Exercise-induced angina Qualitative Nominal
slope Slope of peak exercise ST segment Qualitative Ordinal category
thal Thalassemia category Qualitative Nominal
target Heart disease status Qualitative Nominal

Data Cleaning

The rubric requires us to preserve the original imported data and create a separate cleaned dataset. Therefore, heart_raw remains unchanged and all cleaning is performed on a new object called heart_clean.

Checking Missing Values

     age      sex       cp trestbps     chol      fbs  restecg  thalach 
       0        0        0        0        0        0        0        0 
   exang  oldpeak    slope       ca     thal   target 
       0        0        0        0        0        0 

Checking for Duplicates

[1] 723

Creating the Cleaned Dataset

[1] 302  14
'data.frame':   302 obs. of  14 variables:
 $ age     : int  52 53 70 61 62 58 58 55 46 54 ...
 $ sex     : Factor w/ 2 levels "0","1": 2 2 2 2 1 1 2 2 2 2 ...
 $ cp      : Factor w/ 4 levels "0","1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
 $ trestbps: int  125 140 145 148 138 100 114 160 120 122 ...
 $ chol    : int  212 203 174 203 294 248 318 289 249 286 ...
 $ fbs     : Factor w/ 2 levels "0","1": 1 2 1 1 2 1 1 1 1 1 ...
 $ restecg : Factor w/ 3 levels "0","1","2": 2 1 2 2 2 1 3 1 1 1 ...
 $ thalach : int  168 155 125 161 106 122 140 145 144 116 ...
 $ exang   : Factor w/ 2 levels "0","1": 1 2 2 1 1 1 1 2 1 2 ...
 $ oldpeak : num  1 3.1 2.6 0 1.9 1 4.4 0.8 0.8 3.2 ...
 $ slope   : Factor w/ 3 levels "0","1","2": 3 1 1 3 2 2 1 2 3 2 ...
 $ ca      : int  2 0 0 1 3 0 3 1 0 2 ...
 $ thal    : Factor w/ 4 levels "0","1","2","3": 4 4 4 4 3 3 2 4 4 3 ...
 $ target  : Factor w/ 2 levels "0","1": 1 1 1 1 1 2 1 1 1 1 ...

This approach preserves the original raw data while creating a separate dataset that is ready for summary statistics, visualization, and regression.

Summary Statistics

Before creating our regression model, we examine summary statistics for the quantitative variables.

Summary Statistics for Quantitative Variables
Variable Mean Median SD Minimum Maximum
Age 54.42 55.5 9.05 29 77.0
Resting Blood Pressure 131.60 130.0 17.56 94 200.0
Cholesterol 246.50 240.5 51.75 126 564.0
Maximum Heart Rate 149.57 152.5 22.90 71 202.0
Oldpeak 1.04 0.8 1.16 0 6.2

The table reports the mean, median, standard deviation, minimum, and maximum for each quantitative variable.

Summary Statistics for Qualitative Variables

For qualitative variables, useful summary statistics are the number and percentage of observations in each category.

Summary Statistics for Qualitative Variables
Variable Category Count Percent
cp 0 143 47.4
cp 1 50 16.6
cp 2 86 28.5
cp 3 23 7.6
exang 0 203 67.2
exang 1 99 32.8
fbs 0 257 85.1
fbs 1 45 14.9
restecg 0 147 48.7
restecg 1 151 50.0
restecg 2 4 1.3
sex 0 96 31.8
sex 1 206 68.2
slope 0 21 7.0
slope 1 140 46.4
slope 2 141 46.7
target 0 138 45.7
target 1 164 54.3
thal 0 2 0.7
thal 1 18 6.0
thal 2 165 54.6
thal 3 117 38.7

Together, the quantitative and qualitative tables summarize all of the main variables used in our dataset.

We can also examine a basic summary of every variable.

      age        sex     cp         trestbps          chol       fbs    
 Min.   :29.00   0: 96   0:143   Min.   : 94.0   Min.   :126.0   0:257  
 1st Qu.:48.00   1:206   1: 50   1st Qu.:120.0   1st Qu.:211.0   1: 45  
 Median :55.50           2: 86   Median :130.0   Median :240.5          
 Mean   :54.42           3: 23   Mean   :131.6   Mean   :246.5          
 3rd Qu.:61.00                   3rd Qu.:140.0   3rd Qu.:274.8          
 Max.   :77.00                   Max.   :200.0   Max.   :564.0          
 restecg    thalach      exang      oldpeak      slope         ca        
 0:147   Min.   : 71.0   0:203   Min.   :0.000   0: 21   Min.   :0.0000  
 1:151   1st Qu.:133.2   1: 99   1st Qu.:0.000   1:140   1st Qu.:0.0000  
 2:  4   Median :152.5           Median :0.800   2:141   Median :0.0000  
         Mean   :149.6           Mean   :1.043           Mean   :0.7185  
         3rd Qu.:166.0           3rd Qu.:1.600           3rd Qu.:1.0000  
         Max.   :202.0           Max.   :6.200           Max.   :4.0000  
 thal    target 
 0:  2   0:138  
 1: 18   1:164  
 2:165          
 3:117          
                
                

Visualizing Quantitative Variables

We now visualize each of our main quantitative variables.

Age

This graph shows the age distribution of patients in our sample.

Resting Blood Pressure

Cholesterol

Maximum Heart Rate

Maximum heart rate is particularly important because it is the Y variable that we will attempt to predict with our regression model.

Oldpeak

Visualizing Qualitative Variables

For qualitative variables, bar charts allow us to compare the number of observations in each category.

Sex

Chest Pain Type

Fasting Blood Sugar

Resting ECG

Exercise-Induced Angina

ST Slope

Number of Major Vessels

Although ca is stored numerically, it only takes a small number of discrete values. A bar chart makes the distribution easy to interpret.

Thalassemia Category

Heart Disease Status

Exploring Maximum Heart Rate

Now that we have examined each variable individually, we look more closely at variables that may help explain our Y variable, maximum heart rate.

Age vs. Maximum Heart Rate

The fitted line shows a negative relationship between age and maximum heart rate. In general, older patients in this sample tend to achieve lower maximum heart rates. This pattern is also supported by our regression model, where age has a negative and statistically significant coefficient.

Heart Disease Status vs. Maximum Heart Rate

The boxplots allow us to compare the distribution of maximum heart rate between patients in the two heart disease categories. The regression model later shows that heart disease status is statistically associated with maximum heart rate after controlling for the other explanatory variables.

Exercise-Induced Angina vs. Maximum Heart Rate

Chest Pain Type vs. Maximum Heart Rate

Dependent Variable and Estimating Equation

Our dependent variable is:

Y = thalach (Maximum Heart Rate Achieved)

We estimate increasingly detailed versions of the following relationship:

[ Thalach_i = _0 + _1 Age_i + _2 Sex_i + _3 Target_i + _4 CP_i + _5 Exang_i + _6 Oldpeak_i + _i ]

where (i) represents a patient, (_0) is the intercept, the () coefficients describe estimated relationships between the explanatory variables and maximum heart rate, and (_i) represents other factors affecting maximum heart rate that are not captured by the model.

Because sex, target, cp, and exang are factors, R represents their non-reference categories with indicator variables. Their coefficients are interpreted relative to the omitted reference category.

Three Regression Specifications

We begin with a simple model and then add relevant controls. This allows us to see whether the estimated relationship between age and maximum heart rate changes as additional patient characteristics are included.

Model 1: Simple Age Model


Call:
lm(formula = thalach ~ age, data = heart_clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-65.984 -11.985   4.009  16.004  45.010 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 204.0160     7.4058  27.548  < 2e-16 ***
age          -1.0005     0.1342  -7.452 9.86e-13 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 21.07 on 300 degrees of freedom
Multiple R-squared:  0.1562,    Adjusted R-squared:  0.1534 
F-statistic: 55.54 on 1 and 300 DF,  p-value: 9.858e-13

Model 1 provides the baseline relationship between age and maximum heart rate without additional controls.

Model 2: Add Patient Characteristics


Call:
lm(formula = thalach ~ age + sex + target, data = heart_clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-60.061 -11.818   2.484  12.726  53.618 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 183.0154     8.1707  22.399  < 2e-16 ***
age          -0.7939     0.1301  -6.103 3.23e-09 ***
sex1          1.2379     2.5660   0.482     0.63    
target1      16.4164     2.4486   6.704 1.01e-10 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 19.63 on 298 degrees of freedom
Multiple R-squared:  0.273, Adjusted R-squared:  0.2657 
F-statistic:  37.3 on 3 and 298 DF,  p-value: < 2.2e-16

Model 2 adds sex and heart disease status. Comparing Model 2 with Model 1 shows whether the age coefficient changes after accounting for these characteristics.

Model 3: Full Model


Call:
lm(formula = thalach ~ age + sex + target + cp + exang + oldpeak, 
    data = heart_clean)

Residuals:
    Min      1Q  Median      3Q     Max 
-65.241 -11.189   2.319  12.487  41.435 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 188.4373     8.1034  23.254  < 2e-16 ***
age          -0.7532     0.1257  -5.992 6.08e-09 ***
sex1          0.7259     2.4751   0.293   0.7695    
target1       7.1626     2.8895   2.479   0.0137 *  
cp1           7.8258     3.5514   2.204   0.0283 *  
cp2           4.4549     2.9868   1.492   0.1369    
cp3           9.0015     4.4793   2.010   0.0454 *  
exang1       -8.9980     2.7072  -3.324   0.0010 ** 
oldpeak      -2.4568     1.0687  -2.299   0.0222 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 18.73 on 293 degrees of freedom
Multiple R-squared:  0.3492,    Adjusted R-squared:  0.3314 
F-statistic: 19.65 on 8 and 293 DF,  p-value: < 2.2e-16

Model 3 is the full specification and adds chest pain type, exercise-induced angina, and oldpeak.

Regression Results Table

The three specifications are displayed together below. This makes it easier to compare coefficient estimates, statistical significance, sample size, and model fit across specifications.

Regression Models Predicting Maximum Heart Rate
Dependent variable:
Maximum Heart Rate (thalach)
Model 1 Model 2 Model 3
age -1.000*** -0.794*** -0.753***
(0.134) (0.130) (0.126)
sex1 1.238 0.726
(2.566) (2.475)
target1 16.416*** 7.163**
(2.449) (2.890)
cp1 7.826**
(3.551)
cp2 4.455
(2.987)
cp3 9.001**
(4.479)
exang1 -8.998***
(2.707)
oldpeak -2.457**
(1.069)
Constant 204.016*** 183.015*** 188.437***
(7.406) (8.171) (8.103)
Observations 302 302 302
R2 0.156 0.273 0.349
Adjusted R2 0.153 0.266 0.331
F Statistic 55.539*** (df = 1; 300) 37.298*** (df = 3; 298) 19.650*** (df = 8; 293)
Note: p<0.1; p<0.05; p<0.01

Interpreting and Comparing the Models

When interpreting the table, we focus on three questions:

  1. Does the estimated age coefficient remain negative as controls are added?
  2. Which additional explanatory variables are statistically significant in the fuller specifications?
  3. How does model fit, especially R-squared, change as additional explanatory variables are included?

The exact Model 1 and Model 2 coefficient values should be discussed from the regression table produced when this file is rendered. We do not insert unverified values into the written report.

For Model 3, based on the verified regression output, age has a coefficient of approximately -0.753, exercise-induced angina has a coefficient of approximately -8.998, and oldpeak has a coefficient of approximately -2.457. These relationships are statistically significant at the 0.05 level. Heart disease status and chest pain categories 1 and 3 are also statistically significant, while sex and chest pain category 2 are not statistically significant in the full specification.

Model 3 has an R-squared of approximately 0.349, meaning that the full set of explanatory variables accounts for about 34.9% of the observed variation in maximum heart rate in this sample.

Statistical and Practical Significance

Statistical significance tells us whether the data provide evidence of an association at our chosen significance level. We use a significance level of 0.05.

Practical significance focuses on the size of an estimated relationship. For example, the Model 3 estimate for exercise-induced angina is approximately 9 BPM lower relative to the reference category, which is a much larger estimated difference than a very small fraction of one BPM. We describe this as potentially meaningful in practical terms, but we do not claim a specific clinical threshold because this project does not establish one.

The regression results describe associations, not causal effects.

Regression Diagnostics

Linear regression relies on several assumptions.

We can examine diagnostic plots to determine whether our model appears reasonable.

Residuals vs. Fitted Values

Ideally, the residuals should appear randomly scattered around zero without a strong curved pattern.

Normal Q-Q Plot

If the residuals are approximately normally distributed, most of the points should be reasonably close to the diagonal line.

Actual vs. Predicted Maximum Heart Rate

Our regression model can generate a predicted maximum heart rate for each patient.

First, we add the predictions to our dataset.

We can then compare the model’s predictions with the actual maximum heart rates.

If our model predicts maximum heart rate well, we should see a positive relationship between the predicted and actual values.

Key Findings

Our analysis produced several important findings.

  1. Age was one of the strongest predictors of maximum heart rate. Each additional year of age was associated with approximately a 0.75 BPM decrease in maximum heart rate, holding the other variables constant.

  2. Exercise-induced angina was associated with a lower maximum heart rate. Patients in the exercise-induced angina category had predicted maximum heart rates about 9 BPM lower than the reference group.

  3. Heart disease status was statistically significant. Category 1 was associated with a predicted maximum heart rate approximately 7.16 BPM higher than the reference category.

  4. Chest pain type mattered for some categories. Chest pain types 1 and 3 were statistically significant, while chest pain type 2 was not significant at the 0.05 level.

  5. Oldpeak had a significant negative relationship with maximum heart rate. A one-unit increase in oldpeak was associated with approximately a 2.46 BPM decrease in maximum heart rate.

  6. Sex was not statistically significant after controlling for the other variables in the model.

  7. The model’s R-squared was 0.3492, meaning the model explained approximately 34.9% of the observed variation in maximum heart rate.

Practical Conclusions and Recommendations

The analysis suggests that age, exercise-induced angina, oldpeak, heart disease status, and some chest pain categories contain useful information for explaining differences in maximum heart rate within this dataset.

For analysts or organizations using similar heart-health data, a practical recommendation is to avoid relying on a single characteristic such as age when describing maximum heart rate. The fuller regression specification considers several patient characteristics simultaneously and provides a more complete statistical description.

The model still leaves a substantial amount of variation unexplained. Future analysis should consider additional relevant variables when available and should test whether the results hold in other patient samples.

These recommendations concern data analysis and model building. Because the dataset is observational and this project does not establish clinical thresholds, the results should not be used on their own to make individual medical decisions.

Limitations

Our analysis has several limitations.

First, the dataset is cross-sectional and observational. Therefore, the regression results show associations between variables, but they do not necessarily establish cause and effect.

Second, maximum heart rate can be affected by factors that are not included in this dataset.

Third, our results depend on the patients included in this particular dataset, so they may not perfectly represent every population.

Finally, linear regression makes assumptions about the relationships between the variables. Our diagnostic plots help us evaluate whether these assumptions are reasonable.

# Conclusion

The purpose of this project was to investigate which patient characteristics are associated with maximum heart rate during exercise.

We preserved the raw data, created a separate cleaned dataset, summarized and visualized the major variables, and estimated three increasingly detailed regression specifications. The three-model approach allows us to compare a simple relationship with models that include additional controls.

In the full specification, age, heart disease status, chest pain categories 1 and 3, exercise-induced angina, and oldpeak are statistically significant at the 0.05 level. Sex and chest pain category 2 are not statistically significant in the full model. Model 3 has an R-squared of approximately 0.349, meaning that it explains about 34.9% of the observed variation in maximum heart rate.

Overall, the analysis demonstrates how cross-sectional data and multiple regression can be used to investigate associations between a quantitative outcome and several explanatory variables. Because the data are observational, the results should not be interpreted as causal.

AI Disclosure

Our group used ChatGPT to assist with organizing the Quarto report, generating and revising portions of R code, debugging, and explaining statistical output. We ran the code in R, inspected the resulting tables and visualizations, compared the written interpretations with the actual R output, and remained responsible for the final analysis. Group members reviewed the code so that they could explain the steps used in the project.

Appendix: Sources and Code Assistance

Data Source

Complete before submission: Insert the exact source of heart.csv here, including the page or course source from which the group obtained the raw file.

AI Assistance

OpenAI ChatGPT was used as an aid for code organization, debugging, regression-table formatting, and report structure. AI-generated suggestions were tested in R and revised based on the resulting output.

R Packages Used

  • tidyverse for data manipulation and visualization
  • knitr for formatted tables
  • stargazer for the side-by-side regression-results table

If any additional code is adapted from a website, textbook, class example, or other source, add that source to this Appendix before submission.