About

This page documents the procedure for cleaning and visualizing results from the Central Pennsylvania Observers March 2025 survey.

Survey

Direct link: https://docs.google.com/forms/d/e/1FAIpQLScWSF5_mUWJHatvsmPOE4APbl48tZv0FjzbnmHj8mmAiWLdPQ/viewform?usp=header

Prepare

First, we load the external packages (groups of R commands) that we will be using.

Important

The code uses the quietly() function from the purrr package to suppress most of the feedback.

Code
library('ggplot2')
library('dplyr')

r_functions <- list.files(file.path(here::here(), "src", "R"), "\\.R$", full.names = TRUE)

purrr::map(r_functions, source) |>
  purrr::quietly()
function (...) 
capture_output(.f(...))
<bytecode: 0x11dacca70>
<environment: 0x11daccd48>

Gather

The survey data are stored in a Google Sheet.

Next, we download the data from the Google Sheet where it is collected. Gilmore has stored his Google account credentials in a special environment file that can be accessed by the R command Sys.getenv("GMAIL_SURVEY").

Code
if (!dir.exists(file.path("include", "csv"))) {
  message("Creating missing `include/csv/`.")
  dir.create(file.path("include", "csv"))
}

if (params$update_data) {
  options(gargle_oauth_email = Sys.getenv("GMAIL_SURVEY"))
  googledrive::drive_auth()

  googledrive::drive_download(
    params$gs_name,
    path = file.path("include", "csv", params$csv_fn),
    type = "csv",
    overwrite = TRUE
  )
  message("Data updated.")
} else {
  message("Using stored data.")
}

Clean

We import the downloaded data.

Code
results <- readr::read_csv(file = file.path("include", "csv", params$csv_fn),
                           show_col_types = FALSE)

Shorten long names

The raw question values are as follows:

Code
names(results)
 [1] "Timestamp"                                                                                 
 [2] "Which of the following astronomy activities did you participate in during 2024?"           
 [3] "Which of the following astronomy activities do you plan to participate in during 2025?"    
 [4] "Which of the following activities would you like to get more involved with as a volunteer?"
 [5] "Do you have any particular astronomy goals?"                                               
 [6] "Rate your level of interest in the following activities. [Visual astronomy]"               
 [7] "Rate your level of interest in the following activities. [Astrophotography]"               
 [8] "Rate your level of interest in the following activities. [Science-oriented talks]"         
 [9] "Rate your level of interest in the following activities. [Social gatherings]"              
[10] "Rate your level of interest in the following activities. [Tutorials/how-to's]"             
[11] "Rate your level of interest in the following activities. [Field trips]"                    
[12] "Rate your level of interest in the following activities. [Gear and tech]"                  
[13] "Rate your level of interest in the following activities. [Events for the public]"          
[14] "What is something the club does really well?"                                              
[15] "What is something the club could do to improve?"                                           
[16] "Is there something the club should offer that we are not currently doing?"                 
[17] "Anything else?"                                                                            
[18] "Your name (totally optional)"                                                              

Then, we shorten the long names to make them more useful for data visualization and for making the data dictionary.

Code
renamed_cols <- results |>
  dplyr::rename("time_stamp" = "Timestamp",
                "activities_2024" = "Which of the following astronomy activities did you participate in during 2024?",
                "activities_2025" = "Which of the following astronomy activities do you plan to participate in during 2025?",
                "activities_volunteer" = "Which of the following activities would you like to get more involved with as a volunteer?",
                "astro_goals" = "Do you have any particular astronomy goals?",
                "interest_in_visual" = "Rate your level of interest in the following activities. [Visual astronomy]",
                "interest_in_astrophoto" = "Rate your level of interest in the following activities. [Astrophotography]",
                "interest_in_sci_talks" = "Rate your level of interest in the following activities. [Science-oriented talks]",
                "interest_in_social" = "Rate your level of interest in the following activities. [Social gatherings]",
                "interest_in_how_tos" = "Rate your level of interest in the following activities. [Tutorials/how-to's]",
                "interest_in_field_trips" = "Rate your level of interest in the following activities. [Field trips]",
                "interest_in_gear" = "Rate your level of interest in the following activities. [Gear and tech]",
                "interest_in_public_events" = "Rate your level of interest in the following activities. [Events for the public]",
                "club_does_well" = "What is something the club does really well?",
                "club_could_improve" = "What is something the club could do to improve?",
                "club_should_offer" = "Is there something the club should offer that we are not currently doing?",
                "anything_else" = "Anything else?",
                "respondent_name" = "Your name (totally optional)")

Make data dictionary

Code
data_dict <- data.frame(questions = names(results), shortnames = names(renamed_cols))

Split variables

Some variables have multiple responses. These should ideally be put into separate column variables.

We’ll split the activities* variables first

Code
split_activities <- renamed_cols |>
  dplyr::mutate(
    activities_2024_monthly_mtg = stringr::str_detect(activities_2024, "CPO monthly"),
    activities_2024_skywatch = stringr::str_detect(activities_2024, "CPO hosted Sky watch"),
    activities_2024_eclipse_personal = stringr::str_detect(activities_2024, "Personal eclipse activity"),
    activities_2024_eclipse_club = stringr::str_detect(activities_2024, "Club eclipse trip"),
    activities_2024_bfsp = stringr::str_detect(activities_2024, "Black Forest Star Party"),
    activities_2024_on_tap = stringr::str_detect(activities_2024, "Penn State Astronomy on Tap"),
    activities_2025_monthly_mtg = stringr::str_detect(activities_2025, "CPO monthly"),
    activities_2025_skywatch = stringr::str_detect(activities_2025, "CPO Sky watch"),
    activities_2025_bfsp = stringr::str_detect(activities_2025, "Black Forest Star Party"),
    activities_2025_on_tap = stringr::str_detect(activities_2025, "Penn State Astronomy on Tap")
  )

Then we split astronomy_goals.

Code
split_goals <- split_activities |>
  dplyr::mutate(
    more_scope = stringr::str_detect(astro_goals, "Use my telescope more"),
    buy_gear = stringr::str_detect(astro_goals, "Buy new (to me) gear"),    
    learn_sky = stringr::str_detect(astro_goals, "Learn more about the night sky"),
    astrophoto = stringr::str_detect(astro_goals, "Try astrophotography"),
    meet_folks = stringr::str_detect(astro_goals, "Meet other like-minded folks"),
    plan_trip = stringr::str_detect(astro_goals, "Plan an observing trip")
  ) |>
  dplyr::select(-c(activities_2024, activities_2025, astro_goals))

Drop test cases

Joe and Chris helped test the survey back in December. We’ll drop their test responses.

Code
survey_cleaned <- split_goals |>
  dplyr::filter(!stringr::str_detect(time_stamp, "2024"))

Convert TRUE/FALSE

Code
survey_cleaned <- survey_cleaned |>
  mutate(club_mtg_24 = if_else(activities_2024_monthly_mtg, "yes", "no"),
         skywatch_24 = if_else(activities_2024_skywatch, "yes", "no"),
         eclipse_personal_24 = if_else(activities_2024_eclipse_personal, "yes", "no"),
         eclipse_club_24 = if_else(activities_2024_eclipse_club, "yes", "no"),
         bfsp_24 = if_else(activities_2024_bfsp, "yes", "no"),
         on_tap_24 = if_else(activities_2024_on_tap, "yes", "no"),
         club_mtg_25 = if_else(activities_2025_monthly_mtg, "yes", "no"),
         skywatch_25 = if_else(activities_2025_skywatch, "yes", "no"),
         bfsp_25 = if_else(activities_2025_bfsp, "yes", "no"),
         on_tap_25 = if_else(activities_2025_on_tap, "yes", "no"),
         more_scope = if_else(more_scope, "yes", "no"),
         buy_gear = if_else(buy_gear, "yes", "no"),
         learn_sky = if_else(learn_sky, "yes", "no"),
         astrophoto = if_else(astrophoto, "yes", "no"),
         meet_folks = if_else(meet_folks, "yes", "no"),
         plan_trip = if_else(plan_trip, "yes", "no")
         )

Visualize

As of 2025-12-04 16:24:36.812679, we have had n=28 responses.

Code
# Define helper plot functions
cpo_col_plot <- function(data, var) {
  data |>
    dplyr::filter(!is.na({{ var }})) |>
    count({{ var }}) |>
    ggplot() +
    aes(x = {{ var }}, fill = {{ var }}, y = n) +
    geom_col() +
    geom_text(aes(label = n),
              size = 3,
              position = position_stack(vjust = 0.5)) +
    xlab(NULL) +
    scale_y_continuous(breaks = c(5, 10, 15, 20)) +
    theme(legend.position = "none")
}
# 
# survey_cleaned |> cpo_col_plot(club_mtg_24)

cpo_interest_plot <- function(data, var) {
  data |>
    dplyr::mutate(this_interest = factor({{ var }}, levels = c("Minimal interest", "Some interest", "Considerable interest"))) |>
    dplyr::count(this_interest) |>
    dplyr::filter(!is.na(this_interest)) |>
  ggplot() +
  aes(x = this_interest, fill = this_interest, y = n) +
  geom_col() +
  geom_text(aes(label = n),
              size = 3,
              position = position_stack(vjust = 0.5)) +
  theme(legend.position = "none") +
  xlab(NULL) +
  scale_y_continuous(breaks = c(5, 10, 15, 20))
}

#survey_cleaned |> cpo_interest_plot(interest_in_visual)

Activities 2024/Plans 2025

Club meetings

Which of the following astronomy activities did you participate in during 2024?

Code
survey_cleaned |>
  cpo_col_plot(club_mtg_24)
Figure 1: Attended a club meeting in 2024

Which of the following astronomy activities do you plan to participate in during 2025?

Code
survey_cleaned |>
  cpo_col_plot(club_mtg_24)
Figure 2: Attend a club meeting in 2025

Skywatches

Code
survey_cleaned |>
  cpo_col_plot(skywatch_24)
Figure 3: Attended a skywatch in 2024
Code
survey_cleaned |>
  cpo_col_plot(skywatch_25)
Figure 4: Attend a skywatch in 2025

BFSP

Code
survey_cleaned |>
  cpo_col_plot(bfsp_24)
Figure 5: Attended BFSP in 2024
Code
survey_cleaned |>
  cpo_col_plot(bfsp_25)
Figure 6: Attend BFSP in 2025

PSU On-tap

Code
survey_cleaned |>
  cpo_col_plot(on_tap_24)
Figure 7: Attended Penn State on Tap in 2024
Code
survey_cleaned |>
  cpo_col_plot(on_tap_25)
Figure 8: Attend Penn State on Tap in 2025

2024 Eclipse

Code
survey_cleaned |>
  cpo_col_plot(eclipse_personal_24)
Figure 9: Participated in a personal eclipse activity
Code
survey_cleaned |>
  cpo_col_plot(eclipse_club_24)
Figure 10: Participated in club eclipse trip

Volunteering in 2025

Which of the following activities would you like to get more involved with as a volunteer?

Code
survey_cleaned |>
  dplyr::select(activities_volunteer) |>
  dplyr::filter(!is.na(activities_volunteer)) |>
  knitr::kable(format = 'html')
activities_volunteer
CPO Sky watches
astrophotography with other CPO members
CPO monthly membership meeting, Black Forest Star Party
CPO Sky watches, Other astronomy-oriented public events
Black Forest Star Party, Treasurer
CPO monthly membership meeting, CPO Sky watches
Already involved extensively
Membership, CPO Sky watches, Black Forest Star Party
Black Forest Star Party, Other astronomy-oriented public events
Other astronomy-oriented public events
CPO Sky watches
CPO Sky watches, Black Forest Star Party
Black Forest Star Party
CPO Sky watches, Other astronomy-oriented public events
CPO monthly membership meeting, CPO Sky watches
Black Forest Star Party
CPO monthly membership meeting
Private weekend star party events with other club members
CPO Sky watches, Black Forest Star Party, Other astronomy-oriented public events

Interests

Rate your level of interest in the following activities:

Visual astronomy

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_visual)
Figure 11: Interest in visual astronomy

Astrophotography

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_astrophoto)
Figure 12: Interest in astrophotography

Science talks

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_sci_talks)
Figure 13: Interest in scientific talks

Social gatherings

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_social)
Figure 14: Interest in social gatherings

How-to’s

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_how_tos)
Figure 15: Interest in how-to’s

Gear

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_gear)
Figure 16: Interest in gear

Field trips

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_field_trips)
Figure 17: Interest in field trips

Public events

Code
survey_cleaned |>
  cpo_interest_plot(interest_in_public_events)
Figure 18: Interest in public events

Goals

Do you have any particular astronomy goals?

“Use my telescope more”

Code
survey_cleaned |>
  cpo_col_plot(more_scope)
Figure 19: Use my telescope more

“Buy new (to me) gear”

Code
survey_cleaned |>
  cpo_col_plot(buy_gear)
Figure 20: Buy new gear

“Learn more about the night sky”

Code
survey_cleaned |>
  cpo_col_plot(learn_sky)
Figure 21: Learn more about the night sky

“Try astrophotography”

Code
survey_cleaned |>
  cpo_col_plot(astrophoto)
Figure 22: Learn more about astrophotography

“Meet other like-minded folks”

Code
survey_cleaned |>
  cpo_col_plot(meet_folks)
Figure 23: Meet like-minded folks

“Plan an observing trip”

Code
survey_cleaned |>
  cpo_col_plot(plan_trip)
Figure 24: Plan observing trip

CPO as a club

“What is something the club does really well?”

Code
survey_cleaned |>
  dplyr::select(club_does_well) |>
  dplyr::filter(!is.na(club_does_well)) |>
  knitr::kable(format = 'html')
club_does_well
Thursday's meetings
Communication
BFSP & CPO Public Sky Watch events
Making all members feel wanted, among many other great things.
Food at meetings
Speakers at meetings.
BFSP, monthly meetings
BFSP, monthly speakers
The BFSP. Many people worked hard for many years making the BFSP the success that it was only to have the DCNR pull the rug from under us.
Runs BFSP. Manages our resources. These days we seem to be doing well at bringing in new people and getting participation at meetings.
BFSP
Club membership really enhanced my amateur astronomy experience.
Lectures
The organization of events seems too notch!
It does everything well.
Not sure
Outreach
BFSP
Run the BFSP
Welcoming everyone new! Renee and I were very welcomed at each meeting!
communication with the membership is outstanding

“What is something the club could do to improve?”

Code
survey_cleaned |>
  dplyr::select(club_could_improve) |>
  dplyr::filter(!is.na(club_could_improve)) |>
  knitr::kable(format = 'html')
club_could_improve
Actual club observing
Teach members not to “reply all” to every email.
I remember attending a private CPO star party circa 2015ish that was held at some other CPO members private cabin in the woods where a bunch of members set up telescopes for viewing and astrophotography. I liked the event because members gathered to assist each other and share results... plus the only cost was to travel ~1 hour from state college. I would like to see more of something related to this.
Including astrophysicists and cosmologists as meeting and BFSP speakers.
Meetings run a bit too long
More hardware related discussions
More Astronomy related talks by professors in the research area
The Board needs to be more open and answerable to the membership. The Board serves the members and the membership should be better informed and more participative.
Tone down the complexity of the meeting talks. The intense scientific talks at the beginning of every meeting have gotten very old for me. I've started to come less often because it seems like I need to be a Harvard-educated scientist with six degrees after my name in order to understand any of it. We are an AMATEUR astronomy club, not participants in a science convention.
Maybe social activities - monthly lunch sort of thing if that's not over-kill with monthly meeting
Being a non profit, I feel the Board needs to be transparent and present a Treasurers report at the monthly meetings.
Help each other learn more about observing. Observing gatherings for members.
new member retention
I would donate some equipment, but I think it would sit unused in storage.
more lectures
Facilitating integration of new participants/members seems to be a challenge (all current members seems to know and interact mainly with each other)
Appoint a point person to monitor and interact with DCNR to help keep CPO abreast of DCNR's activities regarding use of state parks for organized astronomy events.
Observing events for members only
Can't think of anything at the moment.
More truly social activities; formal participation in Astro on Tap
Once I got on the email lists, it becomes a bit overwhelming as to what email list we are being emailed about.

“Is there something the club should offer that we are not currently doing?”

Code
survey_cleaned |>
  dplyr::select(club_should_offer) |>
  dplyr::filter(!is.na(club_should_offer),
                !stringr::str_detect(club_should_offer, "N/A")) |>
  knitr::kable(format = 'html')
club_should_offer
A remote meeting option for the monthly club meetings.
Nothing comes to mind.
I'd like to have more club field trips. We used to go to NEAF every year, and I loved it! It was a highlight of my year.
More club outings/trips
Set up some sort of community message board or forum where members can share what they are doing as far as the hobby. Perhaps a comment on a celestial event they witnessed, or a problem they are having or perhaps some item they may have for sale. Keep in mind not everyone is on FB. Maybe this could be a part of our web page...IDK.
CPO lunches
I might offer equipment to other club members, and ask that they pass it on to other members when they are done. I guess that would be a little like an equipment swap.
Restoration of Reflector magazine for members.
See improve answer
I would be interested in have monthly star parties outside of State College. Places like Fairbrook, Lock Haven, Mill Hall, Philipsburg, Centre Hall, etc. It might generate more public interest in astronomy and CPO if we take the show on the road.
Instruction on using telescopes and other devices
can't think of anything

“Anything else?”

Code
survey_cleaned |>
  dplyr::select(anything_else) |>
  dplyr::filter(!is.na(anything_else), 
                !stringr::str_detect(anything_else, "N/A")) |>
  knitr::kable(format = 'html')
anything_else
I look forward to doing more when I retire in a couple of years.
No.
I don't plan to participate in any of the sky watches this year. I'm hesitant to pay money (for parking) to provide an activity that I'm already not being paid for. It feels more like it's not our activity, but Penn State's activity and we're just there to help THEM. Yes, it's good that our name gets out there by partnering with Penn State, but I don't think it's helping to attract young or diverse new members.
I am a charter member. I was very active at one time. Now I am interested in other activities.
No.
I feel like I did a lot for the club and it wasn't appreciated. I've served on the board, helped with talks, helped with BFSP. And feel a little burned out
Not at the moment.
Personally, I do my observing at home, and unfortunately because of continuing conflicts with other endeavors I have not attended a meeting in years. I will attempt to get more involved as a volunteer at the star party.

(Optional) respondent names

Code
survey_cleaned |>
  dplyr::select(respondent_name) |>
  dplyr::filter(!is.na(respondent_name), 
                !stringr::str_detect(respondent_name, "N/A")) |>
  knitr::kable(format = 'html')
respondent_name
Kelly Biggs
Steve Frey
Chris McMullen
Bob S
Wayne Osgood
Gerry Hamilton
Steve Frey
Matt Riggle
Eric Prescott
Amanda Hertlein
David Dix