| Date | Where | What |
|---|---|---|
| Mon Oct 26 | Class | Create the repository, invite the instructor and your reviewer, accept your reviewee’s invite, submit the URL on Canvas |
| Mon Nov 2 | On your own (no meeting) | Part 2: choose data, import it, run the data audit, commit and push |
| Sun Nov 15, 11:59 PM | Home | Proposal due: proposal.qmd and proposal.html pushed |
| Sun Nov 29, 11:59 PM | Home | Draft due: report.qmd with every section started, pushed, renders |
| Mon Nov 30 | Class | Peer review: clone your reviewee’s repo, render it, file a review Issue |
| Wed Dec 2, 11:59 PM | Home | Review Issue filed (if not finished in class) |
| Mon Dec 7 | Class (last class) | Revision workshop: respond to your review, fix, commit |
| Sun Dec 13, 11:59 PM | Home | Response to your review complete on the Issue |
| Wed Dec 16, 11:59 PM | Home | Final due: final push plus a v1.0 tag |
10 Your Project Repository
10.1 Why This Matters
Every assignment so far lived in a Classroom 50 repository that someone else made for you. Your semester project lives in a repository you create, in your own GitHub account, and share with the people who need to see it. That is how you will work on a thesis chapter, a lab analysis, or an agency report after this course: your repository, your history, your decisions about who has access.
This chapter has three parts:
- Create and share the repository (in class, Mon Oct 26).
- Data audit (Mon Nov 2, no class meeting: you work through this part on your own).
- Proposal (due Sun Nov 15, 11:59 PM).
Between Parts 1 and 2, Where The Project Is Going describes the final report, so you can pick data that can carry it.
10.2 Learning Goals
By the end of this chapter, you should be able to:
- create an R project and a private GitHub repository from Positron
- give specific people access to a private repository, and accept an invitation to someone else’s
- keep raw data in
data/raw/and never edit it by hand - run a first data audit on a new dataset and write down what you found
10.3 Vocabulary
| Term | Meaning |
|---|---|
usethis |
An R package that sets up projects, Git, and GitHub from the R console |
| Personal access token (PAT) | A long password-like string that lets R talk to GitHub as you. Treat it like a password: never paste it into a script or a commit |
| Private repository | Only you and the people you add can see it |
| Collaborator | A person you added to your repository. They can see it, clone it, open Issues, and also push changes. Your reviewer will only open Issues, never push |
| Invitation | A collaborator must accept before they have access. Until then, they get a 404 |
| Reviewer / reviewee | You review one person’s project (your reviewee). A different person reviews yours (your reviewer) |
10.5 Common Problems
| You see | What it means | Fix |
|---|---|---|
git_sitrep(): no personal access token found |
R has no token | Route A, Step 2. Restart R after gitcreds_set() |
could not find git or gitcreds errors on Windows |
Command-line Git is not installed | Use Route B today. Install Git for Windows later |
use_github() error with 401 or 403 |
Token expired, or made without the repo scope |
Make a new token with create_github_token() defaults, gitcreds_set(), restart R |
use_github(): already has a GitHub remote |
You ran it twice; the repo already exists | Check github.com. If it is there, you are done |
| Desktop: Publish button missing | Desktop is signed out, or signed in as the wrong account | GitHub Desktop > Settings > Accounts |
| Your reviewer says they get a 404 | They have not accepted your invite yet | They accept at github.com/notifications |
| Project ended up inside a course folder | Git repo inside a Git repo | Delete the new folder (and the GitHub repo if made) and start at Step 0 |
10.6 Where The Project Is Going
The proposal is the first step. The end point is a final report: a Quarto file named report.qmd at the root of your repository, rendered to HTML, 8-12 pages, with these sections: Introduction, Data and Methods, Results, Interpretation, and References if you cite anything. Read this section before you choose your data: the data has to be able to carry everything in the checklist below.
10.6.1 What the final report must show
| Stage | Must show |
|---|---|
| Reproducibility | .Rproj at the root; here() paths only; packages loaded at the top; raw data unedited in data/raw/; renders from a fresh clone; README says how to render |
| Import and inspect | Raw file imported; evidence of inspection; starting row count reported |
| Clean | clean_names(); at least one column type checked and fixed; text problems (case, whitespace, codes) fixed if your data has them; at least one validation check (impossible values, ranges, duplicates); your missing-value decision explained in words |
| Transform | filter() and select(); a new variable with mutate(); a grouped summary; a reshape or a join (or one sentence on why your data did not need one); row counts before and after key steps |
| Visualize | At least 3 figures using at least 2 geom types; each fig-cap describes the pattern; axis labels with units; a colorblind-safe palette |
| Communicate | At least 1 formatted summary table; at least 1 inline R value in the text; interpretation limited to what the data support; an AI Methods Note if you used AI |
| Git | Commits on several dates (not one final dump); the review Issue closed by a commit; a v1.0 tag on the final commit |
When you choose data, check two things against this table: is there something to clean, and is there enough to make three different figures? A tidy, tiny file will make the Clean and Visualize rows hard to show.
10.6.2 Beyond the course
The report also includes one technique not taught in class that you find and learn on your own, chosen because it fits your data. Some ideas:
- a map (
sf) - multi-panel figures (
patchwork) - an interactive plot (
plotly) - a styled table (
gt) - a custom
ggplot2theme - a small function that replaces repeated code
- dates with
lubridate - a simple model (
lm()withbroom) - a parameterized report
Add a short “What I explored” section or callout: what you tried, why it fits your data, where you learned it, and one thing that surprised you. It is graded on fit and explanation, not difficulty. The proposal only asks you to name a tentative idea; you can change it later.
10.6.3 The draft (due Sun Nov 29)
The draft is report.qmd with every section started: Introduction, Data and Methods, Results, and Interpretation all have real content, even if rough. It is pushed, and it renders after Session > Restart R. Your reviewer clones it and renders it the next day, so a draft that does not render, or is mostly empty headings, gives them nothing to review.
Draft checklist. Required for the draft:
Aim to have these in the draft too (all are required in the final): the starting row count, clean_names(), a type fix, a validation check, and your missing-value decision in prose; a grouped summary, a mutate() column, and a reshape or join (or why not) with row counts; 3 figures with 2 geom types, pattern captions, fig-alt, units, and a colorblind-safe palette; one gt table and one inline value; your Beyond-the-course technique with a “What I explored” note.
The draft is complete/incomplete (0 points) on Canvas: submit the address of report.qmd on GitHub. It is what your reviewer reviews.
10.6.4 How the project is graded
| Part | Points | What it covers |
|---|---|---|
| Proposal | 100 | Repository set up and shared, question and data, data audit, plan and figures (see Connect To The Assignment below) |
| Peer review | 100 | Giving a review of your reviewee’s project as a GitHub Issue (60) and responding to the review you receive (40) |
| Final report | 200 | Reproducibility, code, and Git (45); data management and cleaning (40); transformation (25); visualization (35); scientific communication (35); Beyond the course (20) |
Your reviewer does not grade you. The instructor reads the review before grading the final and checks that each problem the reviewer found was fixed or reasonably declined.
A how-to for the peer review (filing and answering the review Issue) and for the v1.0 tag comes before Nov 30. No final submissions are accepted after Sat Dec 19.
10.7 Part 2: Data Audit (Mon Nov 2, On Your Own)
There is no class meeting on Nov 2. Use the class time to do this part. Plan on the full 2.5 hours. Commit and push at least twice (the final project requires commits on several dates).
10.7.1 Choose your data
Your own data is encouraged: a thesis chapter, lab data, agency data. Rules:
- No sensitive data in the repository: landowner or personal information, precise locations of listed species, or anything under a data-use agreement that forbids sharing. Your repository is private, but the instructor and your reviewer can see it. When in doubt, ask before you commit the file.
- GitHub rejects files over 100 MB. For larger data, use a subset and write down how you made it.
Or pick one from the course menu. These are real, messy, public datasets from TidyTuesday, not used in class or assignments:
| Dataset | Main file | What makes it messy |
|---|---|---|
| FrogID frog records | frogID_data.csv |
Citizen-science records: dates, times with time zones, coordinates with uncertainty |
| Christmas Bird Count, Hamilton, Ontario | bird_counts.csv |
Counts per species per year since 1921; survey hours change from year to year |
| Bird baths survey | bird_baths.csv |
Urban vs rural by region; 169 of 161,057 rows have no survey year |
| Seabirds at sea | birds.csv, ships.csv |
Two tables to join (birds per record, ship conditions per record) |
| Ocean temperature, Nova Scotia | ocean_temperature.csv |
Daily means at 7 depths, 2018-2025; look for gaps |
| Global forest area | forest_area.csv |
Countries mixed with regions and a World total (no code) |
| CAL FIRE incidents | week21_calfire_frap.csv |
Fire records with numeric cause codes, agency codes, two date columns |
| Crop yields | key_crop_yields.csv |
Wide: one column per crop; countries mixed with regions (no code) |
Read the dataset’s page (its readme) before you choose. It tells you what each column means, and you need that for the proposal. Then check it against What the final report must show above.
10.7.2 Put the raw file in data/raw/
dir.create(here::here("data", "raw"), recursive = TRUE)Copy (or download) your raw file into data/raw/. Never edit this file by hand. Every change happens in code, so anyone can rerun it from the raw file.
For a menu dataset, download the file with code, so the download itself is recorded. The address is the dataset’s folder on raw.githubusercontent.com plus the file name. For example, the Christmas Bird Count:
download.file(
"https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2019/2019-06-18/bird_counts.csv",
here::here("data", "raw", "bird_counts.csv")
)For another menu dataset, change the date folder (both the year and the full date) and the file name to match the table above.
10.7.3 Start proposal.qmd
In Positron: File > New File > Quarto Document, save it as proposal.qmd in the project root, and paste this starter. Replace every [...].
---
title: "[Project title]"
author: "[Your name]"
date: today
format:
html:
embed-resources: true
execute:
warning: false
message: false
---
## Question
[One paragraph: the research or management question, and the publics who
care about the answer.]
## Data
[Source, who collected it, unit of observation (what one row is), number of
rows and columns, your own data or the course menu, any sharing limits.]
## Data audit
```{r}
library(tidyverse)
library(janitor)
library(here)
raw <- read_csv(here("data", "raw", "[your-file.csv]"))
problems(raw)
glimpse(raw)
```
```{r}
dat <- raw |>
clean_names()
names(dat)
```
```{r}
# NA count per column (across() was the Module 05 Investigate task)
dat |>
summarize(across(everything(), \(x) sum(is.na(x))))
```
**Wrong types and planned fixes:**
- [column]: read as [type], should be [type], because [...]
**One problem or surprise I found:** [...]
## Plan
[Which cleaning, summaries, reshaping (pivots), or joins will the data
need?]
## Three planned figures
1. [Variables, grouping, and the question it answers]
2. [...]
3. [...]
## Beyond the course (tentative)
[One thing you will investigate on your own.]Render it (Preview button). Fix anything that stops the render. Then commit proposal.qmd, proposal.html, and the raw data file, and push.
10.7.4 What a good audit finds
Use the course habits on your own data:
problems()afterread_csv(): values that did not fit the guessed type (Module 03).- Types: numbers read as text, dates read as text, codes read as numbers (Module 04).
- Missing values: how many per column, and what they mean (Module 05).
- What each column means. Total rows mixed with detail rows (Module 05) and cumulative categories that cannot be added (Module 06) were both traps that the code did not catch. The readme or metadata did.
10.8 Try It
Before Nov 2, read the readme for your dataset and answer, in a comment at the top of your audit: what is one row? Write it as “one row is one [thing] at one [time or place]”. If you cannot finish that sentence, the data audit is where you find out.
10.9 Connect To The Assignment
The proposal (due Sun Nov 15, 11:59 PM) is a rendered proposal.html of 2-3 pages at most, built from the starter above. It is worth 100 points:
| Criterion | Points |
|---|---|
| Repository set up, private, instructor and reviewer invited, URL on Canvas | 20 |
| A clear question and publics; data described (source, unit, size, limits) | 20 |
The data audit: import with here(), inspection, clean_names(), type problems named with fixes, NA counts, one problem found |
35 |
| A plan and three planned figures tied to the question | 20 |
| It renders, stays within 3 pages, and names a Beyond-the-course idea | 5 |
There is no weekly assignment for Module 06: the proposal is the work for these two weeks.