About

This page documents some of the steps in our planning process.

W3TM drafted and distributed on 2024-05-28 a member survey using a Google Form. Here are some of the preliminary results.

Note

To reveal the code that generates the following outputs, select the ‘Show All Code’ item from the ‘</> Code’ dropdown menu at upper right.

Set-up

We source some packages to make calls to their functions more convenient.

Code
library(ggplot2)
knitr::opts_chunk$set(tidy = "styler")

Gathering

The Google Form application saves the survey responses as a Google Sheet:

https://docs.google.com/spreadsheets/d/1Rr2kPK16v0tG-c8dm03gl3jqBNqB_DGyQtVcCVmFadg/edit?resourcekey#gid=283208367

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

update_figs <- TRUE

full_survey_data_fn <- file.path("csv", params$survey_data_fn)

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

  new_fn <- file.path("csv", paste0("_", params$survey_data_fn))
  googledrive::drive_download(
    params$survey_sheet_fn,
    path = full_survey_data_fn,
    type = "csv",
    overwrite = TRUE
  )
  message("Data updated.")
} else {
  if (!file.exists(full_survey_data_fn)) {
    warning("File not found: '", full_survey_data_fn, "'.")
    update_figs <- FALSE
  } else {
    message("Using previously stored data.")
  }
}
Auto-refreshing stale OAuth token.
File downloaded:
• 'Field Day 2025 volunteer sign-up (Responses)'
  <id: 1S6ImyrbuiT_HNMaS50KgfxU0XfCneEAcRP_gmmhda8s>
Saved locally as:
• 'csv/narc-fd-2025-survey.csv'
Data updated.

Now, we load the downloaded CSV

Code
if (update_figs) {
  survey_resps <-
    readr::read_csv(full_survey_data_fn, show_col_types = FALSE)
}

names(survey_resps)
 [1] "Timestamp"                                                                                                                                                                                                                          
 [2] "Your Name"                                                                                                                                                                                                                          
 [3] "Callsign"                                                                                                                                                                                                                           
 [4] "Phone"                                                                                                                                                                                                                              
 [5] "Email"                                                                                                                                                                                                                              
 [6] "Do you plan to attend NARC's Field Day 2025?"                                                                                                                                                                                       
 [7] "Do you plan to operate on Field Day?"                                                                                                                                                                                               
 [8] "Are you a night owl and want to operate late into the night or camp out to snag some rare DX?"                                                                                                                                      
 [9] "If you plan to operate, which of the following mode(s) would interest you? \n\nNote: We will have knowledgeable helpers for all modes we use on Field Day, so you are encouraged to try a new mode and will have help if you do so."
[10] "I'm interested in helping with the following activities to promote Field Day and amateur radio to the public..."                                                                                                                    
[11] "Comments or suggestions"                                                                                                                                                                                                            

Cleaning

Then we clean the data by renaming the variables.

Code
survey_resps <- survey_resps |>
  dplyr::rename(
    timestamp = "Timestamp",
    name = "Your Name",
    callsign = "Callsign",
    phone = "Phone",
    email = "Email",
    attend = "Do you plan to attend NARC's Field Day 2025?",
    operate = "Do you plan to operate on Field Day?",
    overnight = "Are you a night owl and want to operate late into the night or camp out to snag some rare DX?",
    help_with = "I'm interested in helping with the following activities to promote Field Day and amateur radio to the public...",
    comments = "Comments or suggestions"
  )

names(survey_resps)[9] <- "modes"

Then we parse variables with multiple values, and conforming some values so that they are easier to visualize.

Code
survey_resps <- survey_resps |>
  # Change timestamp to proper date and time
  dplyr::mutate(timestamp = lubridate::mdy_hms(timestamp, tz = "America/New_York")) |>
  # Change values for 'attend' to make them more easily readable
  dplyr::mutate(
    attend = dplyr::recode(
      attend,
      "Yes, on Saturday June 28" = "sat",
      "Yes, on Sunday June 29" = "sun",
      "Yes, on Saturday June 28, Yes, on Sunday June 29" = "sat_sun",
      "Not sure yet" = "not_sure",
      "Not this year" = "no"
    )
  ) |>
  # Change values for 'operate' to make them lower case
  dplyr::mutate(operate = tolower(operate)) |>
  # Change values for 'overnight'
  dplyr::mutate(overnight = dplyr::recode(
    overnight,
    "Yes, absolutely" = TRUE,
    "Heck no" = FALSE
  )) |>
  # Create new variable for each mode
  dplyr::mutate(
    phone = stringr::str_detect(modes, "Phone"),
    cw = stringr::str_detect(modes, "CW"),
    ft8 = stringr::str_detect(modes, "FT8/FT4"),
    varac = stringr::str_detect(modes, "VarAC"),
    fldigi = stringr::str_detect(modes, "fldigi"),
    js8call = stringr::str_detect(modes, "JS8Call"),
    sstv = stringr::str_detect(modes, "SSTV")
  ) |>
  # Create new variables for each volunteer role
  dplyr::mutate(
    pr = stringr::str_detect(help_with, "PR"),
    info_table = stringr::str_detect(help_with, "table"),
    satellite = stringr::str_detect(help_with, "satellite"),
    mode_expert = stringr::str_detect(help_with, "expert"),
    ed_activity = stringr::str_detect(help_with, "Educational"),
    invite_elected = stringr::str_detect(help_with, "elected"),
    youth = stringr::str_detect(help_with, "youth"),
    food = stringr::str_detect(help_with, "food"),
    clean_up = stringr::str_detect(help_with, "clean-up"),
    test_equipment = stringr::str_detect(help_with, "equipment")
  )

survey_resps$overnight[is.na(survey_resps$overnight)] <- FALSE
survey_resps$pr[is.na(survey_resps$pr)] <- FALSE
survey_resps$info_table[is.na(survey_resps$info_table)] <- FALSE
survey_resps$satellite[is.na(survey_resps$satellite)] <- FALSE
survey_resps$mode_expert[is.na(survey_resps$mode_expert)] <- FALSE
survey_resps$ed_activity[is.na(survey_resps$ed_activity)] <- FALSE
survey_resps$invite_elected[is.na(survey_resps$invite_elected)] <- FALSE
survey_resps$youth[is.na(survey_resps$youth)] <- FALSE
survey_resps$food[is.na(survey_resps$food)] <- FALSE
survey_resps$clean_up[is.na(survey_resps$clean_up)] <- FALSE
survey_resps$test_equipment[is.na(survey_resps$test_equipment)] <- FALSE

It will be easier if we make separate variables for attendance on Sat and Sun, so we do that now.

Code
survey_resps <- survey_resps |>
  dplyr::mutate(
    attend_sat = stringr::str_detect(attend, "sat"),
    attend_sun = stringr::str_detect(attend, "sun")
  ) |>
  dplyr::mutate(attend_any = (attend_sat | attend_sun))

We make all the callsigns uppercase for consistency.

Code
survey_resps <- survey_resps |>
  dplyr::mutate(callsign = toupper(callsign))

Finally, we export the cleaned file.

Code
readr::write_csv(survey_resps, file.path("csv", paste0("clean_", params$survey_data_fn)))

Visualizing

Attending and operating

Here are the number of respondents who plan to attend and their plans to operate.

Code
xtabs(formula = ~ attend + operate, data = survey_resps)
                      operate
attend                 maybe no yes
  not_sure                 3  0   0
  sat                      1  1   4
  sat_sun                  0  0   4
  Sorry, not this year     1  2   1
  sun                      0  0   1
Code
survey_resps |>
  dplyr::select(callsign, attend_sat, overnight, attend_sun) |>
  dplyr::filter(!is.na(attend_sat), !is.na(overnight), !is.na(attend_sun)) |>
  kableExtra::kbl(format = "html") |>
  kableExtra::kable_classic() |>
  kableExtra::column_spec(2,
    color = ifelse(survey_resps$attend_sat == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(4,
    color = ifelse(survey_resps$attend_sun == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(3,
    color = ifelse(survey_resps$overnight == TRUE, "green", "red")
  )
callsign attend_sat overnight attend_sun
W3TM TRUE TRUE TRUE
K3CWP FALSE FALSE FALSE
N3LI TRUE TRUE TRUE
W3EDP TRUE FALSE TRUE
WA7HUB FALSE FALSE FALSE
K3IWI TRUE FALSE FALSE
KF0JZM TRUE TRUE FALSE
W3SWL TRUE FALSE FALSE
N3IW TRUE FALSE FALSE
KC2VCK FALSE TRUE FALSE
N3YUW FALSE FALSE FALSE
K3FOF FALSE FALSE FALSE
K3SKS KC3JAS FALSE FALSE TRUE
K9SDW FALSE FALSE FALSE
KC3AF TRUE FALSE FALSE
W3TRN TRUE FALSE FALSE
KD3BHE FALSE FALSE FALSE
KM3AJ TRUE FALSE TRUE

Modes

Here are respondents’ interests by mode:

Code
attendees <- survey_resps |>
  dplyr::filter(attend_any == TRUE)

modes <- attendees |>
  dplyr::filter(
    !is.na(callsign),
    !is.na(phone),
    !is.na(cw),
    !is.na(ft8),
    !is.na(varac),
    !is.na(fldigi),
    !is.na(js8call),
    !is.na(sstv)
  ) |>
  dplyr::select(callsign, phone, cw, ft8, varac, fldigi, js8call, sstv)

modes |>
  kableExtra::kbl(format = "html") |>
  kableExtra::kable_classic() |>
  kableExtra::column_spec(column = 2, color = ifelse(modes$phone == TRUE, "green", "red")) |>
  kableExtra::column_spec(column = 3, color = ifelse(modes$cw == TRUE, "green", "red")) |>
  kableExtra::column_spec(column = 4, color = ifelse(modes$ft8 == TRUE, "green", "red")) |>
  kableExtra::column_spec(column = 5, color = ifelse(modes$varac == TRUE, "green", "red")) |>
  kableExtra::column_spec(column = 6, color = ifelse(modes$fldigi == TRUE, "green", "red")) |>
  kableExtra::column_spec(column = 7, color = ifelse(modes$js8call == TRUE, "green", "red")) |>
  kableExtra::column_spec(column = 8, color = ifelse(modes$sstv == TRUE, "green", "red"))
callsign phone cw ft8 varac fldigi js8call sstv
W3TM TRUE TRUE TRUE TRUE TRUE TRUE TRUE
N3LI TRUE FALSE TRUE FALSE TRUE TRUE TRUE
W3EDP TRUE FALSE TRUE FALSE TRUE FALSE TRUE
K3IWI TRUE FALSE FALSE FALSE FALSE FALSE FALSE
KF0JZM TRUE TRUE TRUE TRUE TRUE TRUE TRUE
N3IW FALSE TRUE FALSE FALSE FALSE FALSE FALSE
K3SKS KC3JAS TRUE FALSE FALSE FALSE TRUE FALSE FALSE
KC3AF FALSE FALSE TRUE FALSE TRUE TRUE FALSE
KM3AJ TRUE FALSE FALSE FALSE TRUE TRUE FALSE

Volunteering

And here are respondents’ interests in volunteering:

Code
volunteers <- survey_resps |>
  dplyr::select(
    callsign, pr, info_table, satellite, mode_expert,
    ed_activity, invite_elected, youth, food, clean_up, test_equipment
  )

volunteers |>
  kableExtra::kbl(format = "html") |>
  kableExtra::kable_classic() |>
  kableExtra::column_spec(2,
    color = ifelse(volunteers$pr == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(3,
    color = ifelse(volunteers$info_table == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(4,
    color = ifelse(volunteers$satellite == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(5,
    color = ifelse(volunteers$mode_expert == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(6,
    color = ifelse(volunteers$ed_activity == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(7,
    color = ifelse(volunteers$invite_elected == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(8,
    color = ifelse(volunteers$youth == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(9,
    color = ifelse(volunteers$food == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(10,
    color = ifelse(volunteers$clean_up == TRUE, "green", "red")
  ) |>
  kableExtra::column_spec(11,
    color = ifelse(volunteers$test_equipment == TRUE, "green", "red")
  )
callsign pr info_table satellite mode_expert ed_activity invite_elected youth food clean_up test_equipment
W3TM TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
K3CWP FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
N3LI TRUE TRUE FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
W3EDP FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE TRUE TRUE
WA7HUB FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
K3IWI FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
KF0JZM TRUE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE
W3SWL FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
N3IW FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
KC2VCK FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
N3YUW FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
K3FOF FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
K3SKS KC3JAS FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE
K9SDW FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE FALSE
KC3AF FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE TRUE
W3TRN FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
KD3BHE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
KM3AJ FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE