Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trip_purpose table code #35

Open
ashleyasmus opened this issue Jun 6, 2024 · 0 comments
Open

trip_purpose table code #35

ashleyasmus opened this issue Jun 6, 2024 · 0 comments

Comments

@ashleyasmus
Copy link
Contributor

RSG uses the following code to derive the trip purpose table. This is very similar to what is currently in metc.tbi.helper, but removes some 995s, -1s, etc. This code also has some logical checks (stopifnot() checks) to ensure the data run correctly.

## Derive Trip Purpose Table -----------------------------------------
 
dat_all_unified$trip[survey_year == 2019, linked_trip_id := 
                       ifelse(linked_trip_num < 100,
                              paste0(person_id, '0', linked_trip_num), 
                              paste0(person_id, linked_trip_num))]
 
linked_trips =
  dat_all_unified$trip[
    , .(
      # First origin
      o_purpose = first(o_purpose),
      # Last destination
      d_purpose = last(d_purpose),
      # trip weight:
      linked_trip_weight = first(trip_weight),
      # distance (total):
      distance = sum(distance_miles)
    ),
    keyby = .(linked_trip_id, person_id, hh_id, survey_year)
  ]
 
# get rid of change mode trips (origin)
linked_trips = linked_trips[!o_purpose %in% 58]
 
# get rid of change mode trips (destination)
linked_trips = linked_trips[!d_purpose %in% 58]
 
# Derive Non-Imputed Trip Purpose Table ========================================
 
## Split linked trips ----------------------------------------------------------
 
### ... 1 Home-based trips ----------------------
home_purpose = 1
 
# Home-based trips start or end at home
hb = copy(linked_trips)
 
hb = hb[(o_purpose == home_purpose |
           d_purpose == home_purpose)]
 
nrow(hb) / nrow(linked_trips)
# 56% of linked trips are home-based.
 
### ... 2 Non-home-based trips ----------------------
 
# Non-home-based trips neither start nor end at home:
nhb = copy(linked_trips)
nhb = nhb[!linked_trip_id %in%
            hb$linked_trip_id]
 
# Check that nhb trips do not start OR end at home:
stopifnot(nrow(nhb[o_purpose == home_purpose]) == 0)
stopifnot(nrow(nhb[d_purpose == home_purpose]) == 0)
 
 
# Check that the number of linked trips is equal to the categories into which we've split them:
stopifnot(nrow(hb) +  
            nrow(nhb) ==
            nrow(linked_trips))
 
## Assign trip purpose ---------------------------------------------------------
 
### ... 1 Home-based trips ----------------------------------------------------
 
# Home-Based trips get whatever the non-home-based end is:
hb[, purpose := fcase(
  o_purpose == home_purpose | o_purpose == 995 | o_purpose == -1, d_purpose,
  d_purpose == home_purpose | d_purpose == 995 | d_purpose == -1, o_purpose
)]
 
setnames(hb, 
         old = c('linked_trip_weight'),
         new = c('trip_purpose_weight'))
 
### ... 2 Non-home-based trips -------------------------------------------------
 
### ...... one valid end  ------------------------------------------------------
nhb_oneend = nhb[is.na(o_purpose) | is.na(d_purpose) | o_purpose == 995 | d_purpose == 995 | o_purpose == -1 | d_purpose == -1]
nrow(nhb_oneend) # 0
 
# for these single-ended non-home-based trips, assign the purpose to the non-missing end
nhb_oneend[, `:=` (
  purpose = fcase(
    is.na(o_purpose) | o_purpose == 995 | o_purpose == -1,
    d_purpose,
    is.na(d_purpose) | d_purpose == 995 | d_purpose == -1,
    o_purpose
  )
)]
 
setnames(nhb_oneend, 'linked_trip_weight', 'trip_purpose_weight')
 
### ...... two valid ends  -----------------------------------------------------
nhb_twoend = nhb[!is.na(o_purpose) & o_purpose != 995 & o_purpose != -1 &
                   !is.na(d_purpose) & d_purpose != 995 & d_purpose != -1]
 
# check - we've split nhb trips into two complete categories:
stopifnot(nrow(nhb) ==
            nrow(nhb_oneend) +
            nrow(nhb_twoend))
 
# Split into origin and destination:
nhb_twoend_o = copy(nhb_twoend)
nhb_twoend_o = nhb_twoend_o[, `:=` (purpose = o_purpose)]
 
nhb_twoend_d = copy(nhb_twoend)
nhb_twoend_d = nhb_twoend_d[, `:=` (purpose = d_purpose)]
 
# divide NHB trip weight in half:
nhb_twoend_o[, trip_purpose_weight := linked_trip_weight / 2]
nhb_twoend_o[, linked_trip_weight := NULL]
 
nhb_twoend_d[, trip_purpose_weight  := linked_trip_weight  / 2]
nhb_twoend_d[, linked_trip_weight := NULL]
 
 
### 3 Combine  -----------------------------------------------------
trip_purpose = rbindlist(list(hb,
                              nhb_oneend,
                              nhb_twoend_o,
                              nhb_twoend_d),
                         use.names = TRUE)
 
stopifnot(round(sum(
  linked_trips$linked_trip_weight, na.rm = T
)) ==
  round(sum(
    trip_purpose$trip_purpose_weight, na.rm = T
  )))
 
trip_purpose[, sum(trip_purpose_weight, na.rm = T), keyby = purpose]
 
nrow(trip_purpose) / nrow(linked_trips)
# Splitting into origin and destination for our two-ended, nhb trips increased
# the table size by 42%
 
# Mark these as two-ended trips:
trip_purpose[, num_trips_adj := ifelse(linked_trip_id %in% c(nhb_twoend$linked_trip_id), 0.5, 1)]
 
stopifnot(sum(trip_purpose$num_trips_adj) == nrow(linked_trips))
 
# Create trip purpose ID:
# make a sequential linked trip number
 
trip_purpose = trip_purpose[order(hh_id, person_id, linked_trip_id)]
trip_purpose[, trip_purpose_num := 1:.N,
             keyby = .(hh_id, person_id)]
 
# make a linked trip ID with this linked_trip_num
trip_purpose[, trip_purpose_id :=
               bit64::as.integer64(paste0(
                 person_id,
                 str_pad(
                   trip_purpose_num,
                   width = 3,
                   side = "left",
                   pad = "0"
                 )
               ))]
 
stopifnot(uniqueN(trip_purpose$trip_purpose_id) == nrow(trip_purpose))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant