Data 110 Project 2: Astronauts

Author

Lore Elizabeth Nuique

Introduction

The data set I will be conducting my analysis on is about astronauts from the CORGIS Dataset Project (Donald, 2022). It contains data on all the astronauts who have done a space mission before 1/15/2020. CORGIS data set project has an extra link showing who made the data set. It was made by Mariya Stavnichuk and Tatsuya Corlett, using public data from NASA, Roscosmos, and other related websites (Stavnichuk & Corlett, 2020) . I’m interested in this data set because of the recent Artemis II mission, and I’m curious about how many past missions there has been and if there’s an underlying trend. For example, if more females starting going on missions after a certain year.

There are 20 distinct variables. The categorical variables I will be focusing on are astronaut gender and astronaut nationality. The quantitative variables I will be looking at are mission year, mission duration, and astronauts lifetime mission count.

Image: (Glasser, 2026)

Load Libraries and Data Set

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
# highcharter in R

# install.packages(c("highcharter", "RColorBrewer", "dplyr"))

library(highcharter) # for interactive charts
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
library(RColorBrewer) # for color palettes
library(dplyr)
astronauts <- read_csv("astronauts.csv")
Rows: 1270 Columns: 20
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (9): Profile.Name, Profile.Gender, Profile.Nationality, Profile.Selecti...
dbl (10): Profile.Astronaut Numbers.Overall, Profile.Astronaut Numbers.Natio...
lgl  (1): Profile.Military

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(astronauts)
# A tibble: 6 × 20
  Profile.Astronaut Numbers…¹ Profile.Astronaut Nu…² Profile.Name Profile.Gender
                        <dbl>                  <dbl> <chr>        <chr>         
1                           1                      1 Gagarin, Yu… male          
2                           2                      2 Titov, Gher… male          
3                           3                      1 Glenn, John… male          
4                           3                      1 Glenn, John… male          
5                           4                      2 Carpenter, … male          
6                           5                      2 Nikolayev, … male          
# ℹ abbreviated names: ¹​`Profile.Astronaut Numbers.Overall`,
#   ²​`Profile.Astronaut Numbers.Nationwide`
# ℹ 16 more variables: `Profile.Birth Year` <dbl>, Profile.Nationality <chr>,
#   Profile.Military <lgl>, Profile.Selection.Group <chr>,
#   Profile.Selection.Year <dbl>,
#   `Profile.Lifetime Statistics.Mission count` <dbl>, Mission.Role <chr>,
#   Mission.Year <dbl>, Mission.Name <chr>, Mission.Vechicles.Ascent <chr>, …

Data Clean Up

I cleaned this data set by making all the variable names lowercase, so it stays consistent throughout all variables. I used tolower. I also replaced spaces with underscores using gsub.

# Make all variables lowercase
names(astronauts) <- tolower(names(astronauts))

# Replace spaces with underscores
names(astronauts) <- gsub(" ", "_", names(astronauts), fixed = TRUE)
head(astronauts)
# A tibble: 6 × 20
  profile.astronaut_numbers…¹ profile.astronaut_nu…² profile.name profile.gender
                        <dbl>                  <dbl> <chr>        <chr>         
1                           1                      1 Gagarin, Yu… male          
2                           2                      2 Titov, Gher… male          
3                           3                      1 Glenn, John… male          
4                           3                      1 Glenn, John… male          
5                           4                      2 Carpenter, … male          
6                           5                      2 Nikolayev, … male          
# ℹ abbreviated names: ¹​profile.astronaut_numbers.overall,
#   ²​profile.astronaut_numbers.nationwide
# ℹ 16 more variables: profile.birth_year <dbl>, profile.nationality <chr>,
#   profile.military <lgl>, profile.selection.group <chr>,
#   profile.selection.year <dbl>,
#   profile.lifetime_statistics.mission_count <dbl>, mission.role <chr>,
#   mission.year <dbl>, mission.name <chr>, mission.vechicles.ascent <chr>, …

Explore Quantitative and Qualitative variables using Simple Plots

# basic static histogram
data(astronauts)
Warning in data(astronauts): data set 'astronauts' not found
View(astronauts)

hist(astronauts$mission.year, breaks = 10)

I notice here that there is an increase in astronauts being sent on missions between the years of 1990-2000.

# Basic Static Bar chart to see how many female and male astronauts were sent on missions

astronauts %>%
  ggplot(aes(x = profile.gender)) +
  geom_bar()

I notice that there is a very large disparity between the qualitative variable of profile.gender. I may want to explore this further using comparisons from each year.

Visualizations

Bar Chart Graph

I’m utilizing a bar/column chart to show the difference between how many males and females that were sent on a mission each year. I’m using a column chart to show the difference each year and see if there was an increase after a certain year.

# count gender per year 
gender.year <- astronauts |>
  count(mission.year, profile.gender, name = "gender_count")

# save basic chart template
profile_gender_chart <- ggplot(gender.year, aes(x = mission.year, y = gender_count, fill = profile.gender)) + 
  labs(title = "Astronaut Missions by Gender Each Year") +
  xlab("Year") +
  ylab("Astronaut Count") +
  theme_minimal()

profile_gender_chart

# create column chart
profile_gender_chart <- ggplot(gender.year, 
                               aes(x = mission.year, 
                                   y = gender_count, 
                                   fill = profile.gender)) +
  geom_col(
           color = "#888888",
           position = "dodge", # https://ggplot2.tidyverse.org/reference/position_dodge.html 
           alpha = .8) +
  labs(title = "Astronaut Missions by Gender Each Year", caption = "Source: CORGIS Dataset Project") +
  xlab("Year") +
  ylab("Astronaut Count") +
  scale_fill_brewer(palette = "Set1") +
  theme_minimal()

profile_gender_chart

High Charter Graph

There are many countries who have sent astronauts before this data was collected. So, I clean up the data set to focus on a few amount of prominent countries. I found that there are principal space agencies in the United States, Russia, Japan, Canada, and several other European Countries (NASA, 2023). Therefore, I chose to focus on the U.S., Russia, China, Japan, and Germany.

I wanted to focus on a few nationalities, so I utilized filter by profile nationality and the ones I wanted to focus on. Then, I realized mission count may look confusing when graphing it. So I wanted to use count to see how many missions happened for each nationality.

# prepare data using filter
big5 <-
  filter(astronauts, profile.nationality %in% c("U.S.S.R/Russia", "U.S.", "China", "Japan", "Germany"))

# count missions by year to make visualization more clear/easier to code
big5_year <- big5 |>
  count(mission.year, profile.nationality, name = "mission_count")

# make sure data set doesn't have too many observations
nrow(big5_year)
[1] 143
cols <- brewer.pal(5, "Set2")

# stacked area chart
highchart () |>
  hc_add_series(data = big5_year,
                type = "area",
                hcaes(x = mission.year,
                      y = mission_count, 
                      group = profile.nationality)) |>
  hc_colors(cols) |> 
  hc_chart(style = list(fontFamily = "Georgia",
                        fontWeight = "bold")) |>
  hc_plotOptions(series = list(stacking = "normal",
                               marker = list(enabled = TRUE,
                                             states = list(hover = list(enabled = TRUE))),
                               fillOpacity = 0.5,
                               lineWidth = 1,
                               lineColor = "white")) |>
  hc_xAxis(title = list(text="Year")) |>
  hc_yAxis(title = list(text="Mission Count")) |>
  hc_legend(align = "right", verticalAlign = "bottom",
            layout = "vertical") |>
  hc_title(text = "Astronaut Missions by Nationality and Details")
# customize the tooltips to include more detailed information + finalize visualization 

big5_chart <- highchart() |>
  hc_add_series(data = big5_year,
                type = "line",
                hcaes(x = mission.year,
                      y = mission_count, 
                      group = profile.nationality)) |>
  hc_colors(cols) |>
  hc_chart(style = list(fontFamily = "Georgia",
                        fontWeight = "bold")) |>
  hc_xAxis(title = list(text="Mission Year")) |>
  hc_yAxis(title = list(text="Mission Count")) |>
  hc_plotOptions(series = list(marker = list(symbol = "diamond"))) |>
  hc_legend(align = "right", 
            verticalAlign = "top") |>
  hc_tooltip(shared = FALSE,
             borderColor = "black",
             pointFormat = "Nationality: {series.name} Mission Count {point.mission_count}") |>
  hc_title(text = "Astronaut Missions by Nationality and Year") |>
  hc_caption(text = "Data Source: CORGIS Dataset Project")


big5_chart

Scatter Plot Graph for Mission Duration Throughout the Years

I chose to do a scatter plot to show try to see if there is a positive relationship between years and mission duration and I added a linear regression line.

# make scatter plot
duration_chart <- ggplot(astronauts, aes(x = mission.year, y = mission.durations.mission_duration)) +
  labs(title = "Mission Duration Throughout the Years",
       caption = "Source: CORGIS DataSet Project") +
  xlab("Year") +
  ylab ("Mission Length (Days)") +
  theme_minimal(base_size = 12)
duration_chart + geom_point() # add the points

# add linear regression line

duration_chart <- ggplot(astronauts, aes(x = mission.year, y = mission.durations.mission_duration)) +
  labs(title = "Astronaut Mission Duration Throughout the Years",
       caption = "Source: CORGIS DataSet Project") +
  xlab("Year") +
  ylab ("Mission Length (Days)") +
  theme_minimal(base_size = 12)
duration_chart + geom_point() +
  geom_smooth(method='lm',formula=y~x) +
  theme_minimal()

When looking at this visualization, I can see that there is a slight increase in mission length over the years. However, it seems to be pretty split and I think that could be because of several reasons. For example, it could be because more astronauts are doing longer missions in the ISS (International Space Station) rather than 1-5 day missions.

Multiple Linear Regression Analysis

The 3 quantitative variables I’m going to be looking at are mission.durations.mission_duration, mission year, and profile.lifetime_statistics.mission_count. I’m choosing mission duration as a dependent quantitative variable because I want to see which variable impacts how long a space mission can last. I chose mission year because I know as time goes on, technology advances, so I wanted to see if that impacts how long people can stay in space. I chose lifetime mission count because I wanted to see whether astronauts who have participated in more missions have different mission duration. By looking at these variables, I can see if there is a good predictor for mission length.

# find correlations between variables 

# find correlation between mission duration and mission year
cor(astronauts$mission.durations.mission_duration,
    astronauts$mission.year)
[1] 0.3776923
# find correlation between mission duration and lifetime mission count
cor(astronauts$mission.durations.mission_duration,
    astronauts$profile.lifetime_statistics.mission_count)
[1] -0.06912388
# find correlation between mission year and lifetime mission count
cor(astronauts$mission.year,
    astronauts$profile.lifetime_statistics.mission_count)
[1] 0.01693479
# multiple linear regression model
fit1 <- lm(mission.durations.mission_duration ~
             mission.year +
             profile.lifetime_statistics.mission_count,
           data = astronauts)

fit1

Call:
lm(formula = mission.durations.mission_duration ~ mission.year + 
    profile.lifetime_statistics.mission_count, data = astronauts)

Coefficients:
                              (Intercept)  
                               -101889.73  
                             mission.year  
                                    51.75  
profile.lifetime_statistics.mission_count  
                                   -92.65  
summary(fit1)

Call:
lm(formula = mission.durations.mission_duration ~ mission.year + 
    profile.lifetime_statistics.mission_count, data = astronauts)

Residuals:
    Min      1Q  Median      3Q     Max 
-2357.9  -912.2  -577.7   388.5  9389.1 

Coefficients:
                                            Estimate Std. Error t value
(Intercept)                               -1.019e+05  7.062e+03 -14.429
mission.year                               5.175e+01  3.541e+00  14.615
profile.lifetime_statistics.mission_count -9.265e+01  3.180e+01  -2.913
                                          Pr(>|t|)    
(Intercept)                                < 2e-16 ***
mission.year                               < 2e-16 ***
profile.lifetime_statistics.mission_count  0.00364 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1585 on 1267 degrees of freedom
Multiple R-squared:  0.1484,    Adjusted R-squared:  0.147 
F-statistic: 110.4 on 2 and 1267 DF,  p-value: < 2.2e-16

Equation = -101889.73 (intercept) + 51.75 (mission year) - 92.65 (lifetime mission count)

P-value: <2.2e-16

Adjusted R-squared value: 0.147

I wanted to see what this correlation would look like visually, so I used GGally to see the scatterplot matrix.

library(GGally)

# compare the three quantitative variables
ggpairs(astronauts,
        columns = c("mission.durations.mission_duration","mission.year", "profile.lifetime_statistics.mission_count")) 

This equation above can be interpreted as for each additional year, there is a predicted increase of 51.75 days for mission duration for the first slope. For the lifetime mission count slope, the equation says that there is a predicted decrease of 92.65 days for mission duration.

The p-value on the right of mission year has 3 asterisks, which suggests that it may be a key variable in explaining the linear increase for mission duration. The p-value on the right of profile lifetime mission count only has 1 asterisk, which suggests that there is very little correlation between the 2 variables. The p-value given is shown to be statistically significant.

However, the adjusted R-squared value is 0.147. Which means that only about 14.7% of the differences in mission duration can be explained using this model. Which means 85.3% of the differences in mission duration is probably not going to be explained using our model.

Overall Conclusion and Sources

Column Chart Visualization

My first column chart visualization represents the difference between how many male and female astronauts there are. When looking at the graph, you can see that after a certain year, they started having more female astronauts. However, there is still a majority male astronaut population. One surprised I noticed is that between the years of 1960-1965 there was 1 female astronaut, and in the later years none until around 1980. That makes me wonder the context of that outlier. You can see that between the years of 1990s-2000s there was an increase in astronaut missions for both males and females.

I wish I could have included more accurate years on the x-axis without it looking too overcrowded, but I couldn’t get it to work properly.

High Charter Visualization

My high charter visualization represents astronaut missions by nationality and year. The countries I focused on were the main ones of China, Germany, Japan, U.S., and Russia. With the visualization you can see which nationality is sending the most astronauts on missions and what year. I think this visualization is useful because you’re able to see which country is more active in the astronaut/space industry. One interesting thing I noticed is that the U.S. may have send the most missions overall, but they’re experienced a overall downward slope after their peak. However, Russia has a more consistent astronaut mission count.

I wish I could have shown individual astronaut names as well as mission count, but I couldn’t get it to work because the graph would be too overcrowded. I also wish I could have included something like a vertical line with a label that says something like a key event that may of increased or decreased the missions. For example, a vertical line saying like “The Space Race.” I would also like to see more recent astronaut data to see if anything has changed.

Scatterplot Visualization

My scatter plot visualization represents the relationship between years and mission duration. When looking at the graph with the linear regression, you can see that there is a slight positive correlation between the two variables. However, there are many points that are far away from the regression line, even if there is an overall positive correlation. I believe this is because of the advancement in technology and changing society needs for space. For example, maybe now companies like NASA want to focus on longer stays so the astronauts have more time to research. One thing that surprised me was how long some space missions can be. Before looking at this data set, I did not account for the possibility of astronauts staying in space, like in the ISS, for 30+ days.

I wish I could have used an interactive chart to show the individual mission name of each point. However, there would’ve been too many mission names and it may be overcrowded. Additionally, I feel like it would’ve been difficult to pin point which missions are most impactful.

Bibliography

Donald, S. (2022). CORGIS datasets project. Github.Io. https://corgis-edu.github.io/corgis/csv/astronauts/

Dodge overlapping objects side-to-side — Position_dodge. (n.d.). Ggplot2.Tidyverse.Org. https://ggplot2.tidyverse.org/reference/position_dodge.html

Glasser, M. (2026, March 12). NASA sets potential launch date for artemis II mission to the moon. ABC News. https://abcnews.com/Technology/nasa-sets-potential-launch-date-artemis-ii-mission/story?id=131013025

NASA. (2023, September 27). International Space Station cooperation. https://www.nasa.gov/international-space-station/space-station-international-cooperation/

Stavnichuk, Mariya; Corlett, Tatsuya (2020), “Astronaut database”, Mendeley Data, V1, doi: 10.17632/86tsnnbv2w.1