Sunday 7 July 2013

Biking with Children

Spurred by some recent twitter discussions linking to this StackExchange discussion, it's time to finally write this post. I've been thinking about it for an age.

My son was born in Amsterdam, and my daughter in London. We have been, well, not serious bicyclists, but commuters and heavy bicycle users for many years. This didn't stop when we had kids. In Amsterdam, we lived in the center and did everything by bicycle. We had no car, and didn't really miss it. Over our 8 years in London, we've spent 2 years car free, doing the shopping, day trips, etc. by bicycle or by public transit. We aren't sport bicyclists, bent on training and performance, but, well, maybe we're some shade of green.

Early days: < 6 months
Since bicycling is such an integral part of life in Amsterdam, within a couple days of birth, I found myself carrying my baby in a sling while riding my very stable Dutch bike around Amsterdam at slow speeds. This got us to the first health appointments at the GGD, but wasn't really a safe solution. My knees bumped the sling, too, so it wasn't very comfortable. Every time I got back home, I felt like I'd 'gotten away with it' again.

We needed to be able to get around, and a car just wasn't a useful solution, so we got a baby-mee. Baby G's nice, safe carseat clicked into a somewhat springy metal rack attached to my bike rack. Now we could put him in his car seat and continue our bicycle explorations. We got to see some nice places that way.

This was a great way to travel. I could get out of the house really easily with the new baby. He  wasn't heavy yet, so didn't add any instability to the bicycle, and he was strapped into a car seat with decent side impact protection. A low speed fall to the side would be safe. We had a rain cover that zipped over the top when needed. It could also be moved from one bike to another fairly easily, which was great for when my husband was in charge. Mostly it lived on my bike, though, and it was brilliant for trips to the doctor, the zoo, the park.

 But eventually, it was time to move on. For one thing, we needed to carry the shopping, too. And a full shopping bag goes on the back. Yes, Dutch people frequently can be seen with two or more large shopping bags dangling from the handlebars, but I learned early: never follow a Dutch person on a bicycle. The frailest of old ladies will turn across the path of an oncoming tram or down a tricky cobblestone alley full of pedestrians. We won't talk about traffic signals. I'm just not at that level; I know myself, and I don't bike well with shopping on the front.

young, but able:  6 - 15 months
From the time a baby can sit up, the Dutch tend to put them in a 'voorzitje', or front seat. Ours hung on the handlebars with two hooks and had a clamp around the stem. Most newer models have an updated attachment that clamps directly onto the stem. The hooks had a disadvantage in that as the child got heavier, so did the steering, but it was fabulous for several months. As far as I could tell, the babies all love these. It was always exciting, and G would stay awake for at least 30 minutes before starting to nod off, which was fine for dashing about town. We also had plenty of room on the back for groceries.The baby's feet are in foot rests, and you can get a good windscreen to keep out the rain and weather. Our model didn't work with drop handlebars, and if the child fell asleep on the way home from the zoo, it wasn't very comfortable; we were constantly trying to support a lolling head with an elbow while riding. This also made it less useful for longer rides.

For this age, it can also be convenient to have a rack attachment that takes a small folding stroller or pushchair. That way you have something to push around at your destination, which can be a lifesaver if you're headed to a garden, shopping mall, museum or similar walking-heavy destination. I didn't have problems with my knees hitting the voorzitje (pronounced for-zit-ya), but my husband had to spread his knees around it, which isn't the best riding position. If you can, try it out before you buy it.

toddlers:  15 months - 3 years
But after about 15 mo, baby G just grew to be too big. The mini front seats are quite close to the handlebars, so there just isn't room for a larger child. We moved him to a seat on the back. Why not a trailer? Well... we did try out a trailer in Amsterdam once; it was hell. It wasn't the trailer's fault, it was just the nature of Dutch bicycle traffic and Dutch bike infrastructure. The trailer was a bit too wide, a bit too long, and a bit too unexpected to be a comfortable riding experience. One thing that makes a bicycle so useful in Amsterdam is that it is narrow. In a town of narrow, medieval streets, this is essential. Cars generally allowed us about 2 inches of space, because that's how much space a Dutch bicyclist needs, and that's how much room there was on the streets. There were constant obstructions: delivery vans or moving vans or just something going on along a canal.  To get anywhere, the bicyclist has to swerve through the bollards, through a few parking places or along the sidewalks to pass by the obstruction. Then through the bollards again to regain the street. The trailer just didn't have the manoeuvrability we needed.

The Bobike seat, after 5 years in the shed.
It was worse at intersections. Bicycle traffic is chaotic. There is no lane control, no signalling, and if anyone can help it, no braking. Pulling a long, slow load into the midst of 10 or 20 bicyclists all trying to go their separate ways just wasn't a pleasant experience. It didn't feel socially responsible. Everyone else was carrying multiple children on the nice small footprint of their own bicycle, while we had an extraordinary, traffic clogging load. I wanted a lead bike out front warning everyone we were coming through.

But that was Amsterdam, our later trailer experiences were different (see below). In Amsterdam, G sat in a Bobike seat on the back, attached to the rear stays, not the rack. This, again, constricted the room available for groceries, but I put a small basket on the front and did most of my grocery shopping by foot. If I leant forward, I could wear a backpack, but if it sat upright, it was right in the baby's face.

From 15 months  to 3 years old, this was fine, but this guy grew a bit fast, and by 3 years, the seat wasn't working out any more. The clamps holding it to the stays would slip and *bump* he would come down on my fender, providing a very effective brake. I would get off, unload, move the clamps back into place, screw them down as hard as I could and a bit later, *bump*, down they would come again.

Another child seat option that remains useful.
One cause of this difficulty was that we moved to London shortly after G turned 2. He was riding in the same Dutch seat, but the surface was different. When we took the Thames Path to Kew Gardens, it was just too bumpy, with gravel and potholes and rough edges. He was too heavy, and the seat design wasn't up to it. We considered other seats, but none of them really seemed to solve all the problems. A rack-mounted seat certainly would have been better, but we also wanted to go for some longer rides and have something comfortable for G to nap in; we wanted to swap it between bikes; we wanted it to be a bit safer.


small child:  3 - 6 years
So when we saw a second-hand trailer at a boot sale, we got it. (boot sale in British is equivalent to flea market in American English). It wasn't a high end trailer, but it was functional. It had a clamp that tightened onto the bottom stay, with a safety backup strap and a flexible connector to the trailer towing bar. We could lay the bike down and pick it up again without upsetting the trailer. G could nap in it. It was built for two, so he could take a friend. We could swap it between bicycles. (It was more or less equivalent to this one). I put a mirror on my helmet so I could see the traffic behind and keep an eye on the little one.

At 3 yrs old, G started going to nursery 3 days a week. The nursery was 4 miles away, so I biked it with him in the trailer. He could stay cosy and dry while I battled the hill and got a bit of exercise back into my life. We could stop in the park on the way home if the weather was nice. The trailer was very useful, but it lagged: it didn't start smoothly from a stop, but would pull behind in an uncomfortable oscillation. It wasn't dangerous, just unpleasant. My husband liked the functionality of the trailer, but not the execution: too heavy for longer rides.

The response of traffic is mixed, but most people will give you a lot of room. When people see the trailer, they generally say 'Awww, or 'Wow' or 'what a way to travel'... we get a lot of comments. There is a real feeling of support for this approach. London traffic treats you differently as a bicyclist or as a bicyclist with a trailer. On most roads, I didn't feel pressured to move out of the way or to get a move on. Sometimes the white van guys will even wave at my passenger. There is (slightly) more understanding that you are carrying a load, and the load is precious.

We were wanting some longer rides. We organised a trip to Southern France with some friends, and we bought a Burley. The first several times I pulled it, I kept checking to see that it was actually behind me. It felt extremely smooth and light compared to the other trailer.

G was comfortable and very happy with his space in the trailer. On a long ride, there wasn't so much for him to do, but we took frequent breaks and found a lot of waterfalls. He got more chocolate croissants than any child should expect. We could hand him long pieces of grass and things to look at and hold out into the breeze. He would nap and re-arrange his environment. This is the kind of biking that you cannot do with a child in a seat.

The Burley folded flat and fit into a luggage rack on the Eurostar and TGV trains. It was easy enough to convert that we rode it across Paris from Gare du Nord to Gare d' Est and folded it again for the second train.

second time around:
And then came P. We live near a busy train track, and the crossing bars are down a lot. During the week it's easily 40 minutes out of the hour. Since G's school and the local shops are on the other side, most of our daily trips involve stairs. I walked everywhere when P was small. I could carry her lightweight pushchair over the stairs, where I wouldn't have been able to manage either a bike with seat or a trailer. I didn't have the baby-mee, but I occasionally put her carseat in the trailer to ride somewhere. There wasn't a very good attachment for this, but I could strap it in for stability, and she was reasonably well-protected. She would eventually complain if the road was bumpy, so we took the speed bumps very slowly and tried to stay off of the Thames Path.

She has missed out on the fun of the voorzitje, but she enjoys going for bike rides. She has her own space in the trailer, and often doesn't want to get out when we arrive. She brings along a stuffed animal and can often be heard making up a song or game while we travel. We haven't considered getting a bike seat for her. Actually, I just cleared out the old rear seat from the shed.


Minimalist child seat.
As a sturdy 4 1/2 year old, P is now going to nursery about 1/2 mile away. We have tried out all the possible methods of transit; some days we even seem to crawl. On the bike, there are three possibilities: the trailer, the back rack or the top tube. One boy at her nursery arrives on a seat on his father's top tube (pictured). When she's in front of me, my knees have to go wide around her, and neither of us is comfortable for longer rides. On the touring bike, I am leaned forward over her, and this riding position is quite cosy. She is forced to lean over as well, just to fit into the available space. On the other hand, being up high and in front is exciting. She has to face the weather. For the past couple of weeks, though, the trailer has been the method of choice.

more than one:
typical scene in Amsterdam, shamelessly borrowed from this blog
Since G was already nearly 6 when P was born, we didn't have to do a lot of riding while carrying two children. I did hand on our 1st trailer to a nearby family who used it happily for the school run. This can be a tricky time - when the younger child is in nursery, there is about a year with three school runs a day, and many young children just aren't up to that much walking. A two seat trailer is a good solution, and generally cheaper and more flexible than a box-bike or tricycle.

Although Dutch town are filled with scenes of whole families riding on one bike, it can be difficult to manage. The front-seat + back-seat combination is the most common. This works reasonably well when the children are small, but the problem is always how to load it safely. Basically, a toddler's weight on a leaning bike is already half-way to an accident. The best solution seems to be to load the baby in front first, stabilize the bicycle, and have the toddler climb into their seat. Invest in a really solid kick stand that will give more than one point of support, and hold the brakes tightly on to keep the bike from rolling while they climb up. A stop or velcro strap that keeps the front wheel from turning can also help. Even when the children are in place, however, you still have to clip the toddler's straps, which requires an extra hand. I witnessed more than one fall, and more than one utterly frazzled mother. If you're just headed to the park with your partner, distribute the weight and put a seat on each bike.

If you have to lean the bike to get your leg over the top bar, be extremely cautious. Having all the children's weight at the top of the bike makes it very unstable. Holding onto a brake will keep it from rolling, but... it's just a tippy machine at this point.

Summary:
There are many options for riding with your children. Which one(s) you choose will depend on the children's ages and your own bicycling style and needs. We found that seats worked very well in the confines of medieval streets in Amsterdam and also for errands and short trips in London. They work better with a step-through frame (no or low top-tube) and an upright riding position. Outside of Amsterdam, the trailer was the way to go for us. It requires more storage space and actual, normal sized roads. It can carry a heavy load without any instability. We take it on and off the bicycle for each trip, which requires some attention to detail -- never leave off the safety strap! This takes less than 1 minute after a bit of practice. Since we use the trailer for vacations and daily errands, including shopping runs, it has definitely been worth the price.

Right now we are packing to move back to the US, and we'll be taking the Burley with us.










Saturday 6 July 2013

Idiom in R: results you can C

Computing for Data Analysis was a pretty good introduction to R, but did not really talk about R idiom, which can make the difference between code that runs and code that runs quickly. Here is a basic example.

Using sprintf statements for formatting filenames: Consider a series of files. The goal is to read them all into R, but the filenames include a constant width variable: we're looking to load filenames such as ./data/001.csv and ./data/011.csv up to ./data/999.csv. How do we construct the name strings in R?

The numbers in the file names need to be padded and converted to the appropriate strings. Here are three ways of doing the padding.

The R way:

# setup
directory <- "data"
id = 1:999

# method 1
pad.R <- function(id) {
    num <- sprintf("%03d", as.integer(id))
    path <- paste("./", directory, "/", num, ".csv", sep = "")
    return(path)
}

A brute-force method:

# method 2
pad.brute <- function(id) {
    num <- rep("", length(id))
    for (n in 1:length(id)) {
        if (id[n] < 10)  num[n] <- paste("00", id[n], sep = "") 
  else if (id[n] < 100)  num[n] <- paste("0", id[n], sep = "") 
  else num[n] <- as.character(id[n])
    }

    path <- paste("./", directory, "/", num, ".csv", sep = "")
    return(path)
}

… but we know that for-loops are notoriously slow in R, so we could take a hybrid approach and define a function to take a single number as input and convert it. Then that function could be used with one of R's apply methods to convert the vector in one go.

A hybrid method:

# method 3
padder <- function(num) {
    if (num < 10) return(paste("00", num, sep = "")) 
 else if (num < 100) return(paste("0", num, sep = "")) 
 else return(as.character(num))
}

pad.hybrid <- function(id) {
    num <- sapply(id, padder)
    path <- paste("./", directory, "/", num, ".csv", sep = "")
    return(path)
}

Comparison

These approaches all give the same results, but they are noticeably different.

system.time(path <- pad.R(id))
##    user  system elapsed 
##   0.001   0.000   0.001
system.time(path <- pad.brute(id))
##    user  system elapsed 
##   0.007   0.000   0.008
system.time(path <- pad.hybrid(id))
##    user  system elapsed 
##   0.004   0.000   0.004
path[c(3, 13, 103)]
## [1] "./data/003.csv" "./data/013.csv" "./data/103.csv"

For speed, they are equivalent when run on 1 or two elements at a time. However, when run on the full 999 element vector as shown here, both the 'brute force' and 'hybrid' methods are significantly slower than sprintf.

The discussions on the course forums did give a different perspective. Several self-identified 'professional programmers' preferred the if, if-else, else approach I've used in both methods 2 and 3. They considered it more readable and thus more maintainable.

I don't think this is the best approach. If you are a professional programmer, you are familiar with idiom, in whatever language you work in. You know that there are readable, maintainable, ways of doing what needs to be done efficiently. At it's root, deep down underneath, R is in the C family of languages. The basic in/out is based on the C standard library <stdio.h>. The professional way to use R is to use that R idiom efficiently and in a way that other R programmers will understand.

So learn your sprintf formatting codes. They may look like magic numbers the first time you meet them, but they are systematic and ubiquitous. They will be useful in many other contexts, including modern languages like Python and Java and therefore even Scala and Clojure. They will also speed up your code, and don't worry, most other professionals will understand them.