@@ -123,195 +123,215 @@ create_global_scenarios <- function(trip_set) {
123123 trip_set <- NULL
124124
125125 rd_list <- list ()
126+
127+ # define the modes that can't be changed
128+ modes_not_changeable <- c(" bus_driver" , " truck" , " car_driver" , " taxi" )
129+
130+
131+ # # to get overall trip shares for the distance bands - needed if want to updated global_modeshares
132+ # rdr_modeshares <- rdr |>
133+ # filter(participant_id !=0) |>
134+ # distinct(trip_id, .keep_all = T) |>
135+ # count(trip_mode, trip_distance_cat) |> mutate(freq = prop.table(n), .by = trip_mode) |>
136+ # filter(trip_mode %in% c('cycle', 'car', 'bus', 'motorcycle')) |>
137+ # dplyr::select(-n) |>
138+ # dplyr::mutate(freq = round(freq * 100, 1)) |>
139+ # pivot_wider(names_from = trip_distance_cat, values_from = freq) |>
140+ # dplyr::mutate(cityname = city)
141+ #
142+ # # add these city specific numbers to a dataframe containing all the numbers
143+ # if (exists('total_modeshares') && is.data.frame(get('total_modeshares'))){
144+ # total_modeshares <- rbind(total_modeshares, rdr_modeshares)
145+ # } else {
146+ # total_modeshares <- rdr_modeshares
147+ # }
148+ #
149+ # total_modeshares <<- total_modeshares # create global variable
126150
127151 # global modal split across the three distance categories for each mode
128152 # cycle, car, bus, motorcycle
129153 global_modeshares <- data.frame (
130- c(38.5 , 9 .4 , 2.1 , 10.7 ), # distance category 0-2km
131- c(50 , 45.7 , 33.5 , 37.2 ), # distance category 2-6km
132- c(11.5 , 44.9 , 64.4 , 52.6 )
154+ c(39.0 , 10 .4 , 4.8 , 10.8 ), # distance category 0-2km
155+ c(50.0 , 45.5 , 39.7 , 38.0 ), # distance category 2-6km
156+ c(11.0 , 44.1 , 55.5 , 51.2 )
133157 )
158+
159+ colnames(global_modeshares ) <- DIST_CAT
160+ rownames(global_modeshares ) <- c(" cycle" , " car" , " bus" , " motorcycle" )
134161
135- percentage_change <- SCENARIO_INCREASE
162+ percentage_change <- SCENARIO_INCREASE # increase of each mode as percentage of total number of trips.
136163
137164
138165 rdr_baseline <- rdr %> %
139166 dplyr :: select(c(" trip_id" , " trip_distance_cat" , " scenario" , " trip_mode" )) %> %
140167 filter()
141- rdr_baseline <- rdr_baseline %> % distinct()
168+ rdr_baseline <- rdr_baseline %> % distinct() # remove any duplicates (for when there are multiple stages)
142169
143- no_trips <- nrow(rdr_baseline )
144- prop_0_2 <- nrow(rdr_baseline %> % filter(trip_distance_cat == " 0-2km" )) / no_trips
145- prop_2_6 <- nrow(rdr_baseline %> % filter(trip_distance_cat == " 2-6km" )) / no_trips
146- prop_6 <- nrow(rdr_baseline %> % filter(trip_distance_cat == " 6+km" )) / no_trips
170+ no_trips <- nrow(rdr_baseline ) # total number of trips
171+
172+ # proportion of total trips in each distance category
173+ prop <- list ()
174+ for (i in DIST_CAT ) {
175+ prop [[i ]] <- nrow(rdr_baseline %> % filter(trip_distance_cat == i )) / no_trips
176+ }
177+
147178
148179 # initialise the proportions to be added in each scenario
149180 scenario_proportions <- data.frame (
150181 c(0 , 0 , 0 , 0 ), # distance category 0-2km
151182 c(0 , 0 , 0 , 0 ), # distance category 2-6km
152183 c(0 , 0 , 0 , 0 )
153184 )
154- # add the correct values
155- for (r in 1 : 3 ) {
156- for (c in 1 : 4 ) {
157- if (r == 1 ) {
158- percentage_trips <- prop_0_2
159- } else if (r == 2 ) {
160- percentage_trips <- prop_2_6
161- } else {
162- percentage_trips <- prop_6
163- }
164- scenario_proportions [c , r ] <- percentage_change * global_modeshares [c , r ] / percentage_trips
185+
186+ # add row and column names
187+ colnames(scenario_proportions ) <- colnames(global_modeshares )
188+ rownames(scenario_proportions ) <- rownames(global_modeshares )
189+
190+ # find the proportion of trips to be converted for each distance category and scenario
191+ for (c in colnames(scenario_proportions )) {
192+ for (r in rownames(scenario_proportions )) {
193+ scenario_proportions [r , c ] <- percentage_change * global_modeshares [r , c ] / prop [[c ]]
165194 }
166195 }
167-
168-
169- colnames(scenario_proportions ) <- target_distances <- DIST_CAT
170- rownames(scenario_proportions ) <- modes <- c(" cycle" , " car" , " bus" , " motorcycle" )
196+
197+
171198 SCENARIO_PROPORTIONS <<- scenario_proportions
172-
199+
173200 # print(scenario_proportions)
174201
175202 # baseline scenario
176- rd_list [[1 ]] <- rdr
177- modes_not_changeable <- c(" bus_driver" , " truck" , " car_driver" )
203+ rd_list [[" baseline" ]] <- rdr
204+
205+ # create data frame containing all the trips that are not going to be changed in a scenario
206+ # i.e. bus_driver, truck and car_driver trips but also commercial motorcycle trips which have a participant id of 0
178207 rdr_not_changeable <- rdr %> % filter(trip_mode %in% modes_not_changeable | participant_id == 0 )
179- rdr_changeable <- rdr %> % filter(! trip_mode %in% modes_not_changeable & ! participant_id == 0 ) # Trips that can be reassigned to another mode
180-
181-
182- # Split trips by distance band in a new list
208+
209+ # Trips that can be reassigned to another mode
210+ rdr_changeable <- rdr %> % filter(! trip_mode %in% modes_not_changeable & ! participant_id == 0 )
211+
212+ # Split the changeable trips by distance band, save in a new list
183213 rdr_changeable_by_distance <- list ()
184- for (j in 1 : ncol(SCENARIO_PROPORTIONS )) {
185- target_distance <- target_distances [j ]
214+ for (j in colnames(SCENARIO_PROPORTIONS )) {
186215 rdr_changeable_by_distance [[j ]] <- rdr_changeable %> %
187- filter(trip_distance_cat == target_distance )
216+ filter(trip_distance_cat == j )
188217 }
189218 rdr_changeable <- NULL
190-
219+
191220 # split all trips by distance band
192221 rdr_all_by_distance <- list ()
193- for (j in 1 : ncol(SCENARIO_PROPORTIONS )) {
194- target_distance <- target_distances [j ]
222+ for (j in colnames(SCENARIO_PROPORTIONS )) {
195223 rdr_all_by_distance [[j ]] <- rdr %> %
196- filter(trip_distance_cat == target_distance )
224+ filter(trip_distance_cat == j )
197225 }
198-
199226 rdr <- NULL
227+
200228
201229 # ##############################################################
202230 # Creation of scenarios
203231 scen_warning <- c()
204-
205- for (i in 1 : nrow(SCENARIO_PROPORTIONS )) { # Loop for each scenario
206- mode_name <- modes [i ] # mode of the scenario
232+
233+ for (i in rownames(SCENARIO_PROPORTIONS )) { # Loop for each scenario
207234 rdr_copy <- list ()
208- for (j in 1 : ncol(SCENARIO_PROPORTIONS )) { # Loop for each distance band
235+
236+ for (j in colnames(SCENARIO_PROPORTIONS )) { # Loop for each distance band
209237 rdr_copy [[j ]] <- rdr_changeable_by_distance [[j ]] # Trips in the distance band
210- if (mode_name != " bus" ) {
238+
239+ if (i != " bus" ) {
211240 # Identify the trips_id of trips that weren't made by the trip mode
212- potential_trip_ids <- unique(rdr_copy [[j ]][! rdr_copy [[j ]]$ trip_mode %in% c(mode_name ), ]$ trip_id )
213-
241+ potential_trip_ids <- unique(rdr_copy [[j ]][! rdr_copy [[j ]]$ trip_mode %in% c(i ), ]$ trip_id )
242+
214243 # Count the number of trips that were made by the trip mode
215244 current_mode_trips <- rdr_copy [[j ]] %> %
216- filter(trip_mode == mode_name ) %> %
245+ filter(trip_mode == i ) %> %
217246 distinct(trip_id ) %> %
218247 nrow()
219- } else {
248+ } else { # consider bus and rail trips together
249+
220250 # Identify the trips_id of trips that weren't made by the trip mode
221- potential_trip_ids <- unique(rdr_copy [[j ]][! rdr_copy [[j ]]$ trip_mode %in% c(mode_name , " rail" ), ]$ trip_id )
222-
251+ potential_trip_ids <- unique(rdr_copy [[j ]][! rdr_copy [[j ]]$ trip_mode %in% c(i , " rail" ), ]$ trip_id )
252+
223253 # Count the number of trips that were made by the trip mode
224254 current_mode_trips <- rdr_copy [[j ]] %> %
225- filter(trip_mode %in% c(mode_name , " rail" )) %> %
255+ filter(trip_mode %in% c(i , " rail" )) %> %
226256 distinct(trip_id ) %> %
227257 nrow()
228258 } # End else
229- target_percent <- SCENARIO_PROPORTIONS [i , j ]
230- # n_trips_to_change <- round(length(unique(rdr_copy[[j]]$trip_id)) *
231- # target_percent / 100) # These trips will be reassigned
259+
260+ # These number of trips will be reassigned
232261 n_trips_to_change <- round(length(unique(rdr_all_by_distance [[j ]]$ trip_id )) *
233- target_percent / 100 ) # These trips will be reassigned
234- # print(n_trips_to_change)
262+ SCENARIO_PROPORTIONS [i , j ] / 100 )
263+
264+
235265 if (length(potential_trip_ids ) > 0 & n_trips_to_change > 0 ) {
236266 # if the number of trips that could be changed equals the number of trips that need to be changed
237267 if (length(potential_trip_ids ) == n_trips_to_change ) {
238268 change_trip_ids <- potential_trip_ids
239-
269+
240270 # if there are less trips to change than should be changed
241271 } else if (length(potential_trip_ids ) < n_trips_to_change ) {
242272 # save name of scenario
243- scen_warning <- c(scen_warning , rownames( SCENARIO_PROPORTIONS )[ i ] )
244-
273+ scen_warning <- c(scen_warning , i )
274+
245275 # convert all trips possible
246276 change_trip_ids <- potential_trip_ids
247-
248- # if there are more trips that can be changed than need to be changed, sample
249- } else if (length(potential_trip_ids ) > n_trips_to_change ) {
277+ } else { # if there are more trips that can be changed than need to be changed, sample
250278 change_trip_ids <- base :: sample(potential_trip_ids ,
251- size = n_trips_to_change
279+ size = n_trips_to_change
252280 )
253281 }
254- change_trips <- rdr_copy [[j ]][rdr_copy [[j ]]$ trip_id %in% change_trip_ids , ]
255- change_trips $ trip_mode <- mode_name
256- change_trips $ stage_mode <- mode_name
282+
283+ # convert the trips to the new mode
284+ change_trips <- rdr_copy [[j ]][rdr_copy [[j ]]$ trip_id %in% change_trip_ids , ] # extract trips to be changed
285+ change_trips $ trip_mode <- i # assign a new trip mode name
286+ change_trips $ stage_mode <- i # assign a new stage mode name
287+
288+ # update the trip duration based on the new mode speeds
257289 change_trips $ stage_duration <- change_trips $ stage_distance * 60 /
258- MODE_SPEEDS $ speed [MODE_SPEEDS $ stage_mode == mode_name ]
259-
260- # Replace trips reassigned in the trip dataset and save them in a new list
290+ MODE_SPEEDS $ speed [MODE_SPEEDS $ stage_mode == i ]
291+
292+ # Replace trips reassigned in the trip dataset and save all trips in a new list
261293 rdr_copy [[j ]] <-
262294 rbind(
263295 rdr_copy [[j ]][! rdr_copy [[j ]]$ trip_id %in% change_trip_ids , ],
264296 change_trips
265297 )
266298 }
267299 } # End loop for distance bands
268- rdr_scen <- do.call(rbind , rdr_copy )
269- rdr_scen <- rbind(rdr_scen , rdr_not_changeable )
270-
300+
301+ rdr_scen <- do.call(rbind , rdr_copy ) # bind across all distance bands
302+ rdr_scen <- rbind(rdr_scen , rdr_not_changeable ) # add trips that could not be changed
303+
271304 # Remove bus_driver from the dataset, to recalculate them
272305 if (ADD_BUS_DRIVERS ) {
273306 rdr_scen <- filter(rdr_scen , ! trip_mode %in% " bus_driver" )
274307 rdr_scen <- add_ghost_trips(rdr_scen ,
275- trip_mode = " bus_driver" ,
276- distance_ratio = BUS_TO_PASSENGER_RATIO * DISTANCE_SCALAR_PT ,
277- reference_mode = " bus" ,
278- agerange_male = BUS_DRIVER_MALE_AGERANGE ,
279- agerange_female = BUS_DRIVER_FEMALE_AGERANGE ,
280- scenario = paste0(" Scenario " , i )
308+ trip_mode = " bus_driver" ,
309+ distance_ratio = BUS_TO_PASSENGER_RATIO * DISTANCE_SCALAR_PT ,
310+ reference_mode = " bus" ,
311+ agerange_male = BUS_DRIVER_MALE_AGERANGE ,
312+ agerange_female = BUS_DRIVER_FEMALE_AGERANGE ,
313+ scenario = paste0(" sc_ " , i )
281314 )
282- # print(paste("Scenario name: ", paste0('Scenario ',i)))
283- bus_dr_dist <- sum(rdr_scen [rdr_scen $ stage_mode == " bus_driver" , ]$ stage_distance , na.rm = T )
284- bus_dist <- sum(rdr_scen [rdr_scen $ stage_mode == " bus" , ]$ stage_distance , na.rm = T )
285315 }
286-
287-
288- # print(bus_dr_dist/bus_dist)
289-
290-
316+
291317 # Remove car_driver from the dataset, to recalculate them
292318 rdr_scen <- filter(rdr_scen , ! trip_mode %in% " car_driver" )
293319 if (ADD_CAR_DRIVERS ) {
294320 rdr_scen <- add_ghost_trips(rdr_scen ,
295- trip_mode = " car_driver" ,
296- distance_ratio = car_driver_scalar * DISTANCE_SCALAR_CAR_TAXI ,
297- reference_mode = " car" ,
298- scenario = paste0(" Scenario " , i )
321+ trip_mode = " car_driver" ,
322+ distance_ratio = car_driver_scalar * DISTANCE_SCALAR_CAR_TAXI ,
323+ reference_mode = " car" ,
324+ scenario = paste0(" sc_ " , i )
299325 )
300- # print(paste("Scenario name: ", paste0('Scenario ',i)))
301- car_dr_dist <- sum(rdr_scen [rdr_scen $ stage_mode == " car_driver" , ]$ stage_distance , na.rm = T )
302- car_dist <- sum(rdr_scen [rdr_scen $ stage_mode == " car" , ]$ stage_distance , na.rm = T )
303326 }
304-
305- # print(car_dr_dist/car_dist)
306- rdr_scen $ scenario <- paste0(" sc_" , rownames(SCENARIO_PROPORTIONS )[i ])
307- rd_list [[i + 1 ]] <- rdr_scen
327+
328+ rdr_scen $ scenario <- paste0(" sc_" , i ) # add scenario name
329+ rd_list [[i ]] <- rdr_scen # create output list by adding trips for each scenario
308330 } # End loop for scenarios
309-
310-
311-
331+
312332 # print warning message if there weren't enough trips to be converted for a scenario
313333 scen_warning <- unique(scen_warning )
314-
334+
315335 if (length(scen_warning ) > 0 ) {
316336 for (j in 1 : length(scen_warning )) {
317337 print(paste0(
@@ -320,6 +340,8 @@ create_global_scenarios <- function(trip_set) {
320340 ))
321341 }
322342 }
323-
343+
344+
345+
324346 return (rd_list )
325347}
0 commit comments