Add ablity to sample a dataframe

If you have a ordered or sorted DataFrame then just looking at the head or tail may give you a very unrepresentative view of the data. This PR extends `sample` to sample rows from a DataFrame. 

While adding tests for `sample()` I also added a few tests for `head()` and `tail()`.

One thing I want to ask is what the policy is for type annotations for function arguments. I've annotated `n` to `Integer` which is what it is annotated with in StatsBase. Would it be better to leave it as something more generic and just delegate the method error to the StatsBase sample method?

One shortcoming of the current implmentation is that the DataFrame resulting from the sampling doesn't save the row numbers of the original DataFrame so you don't know which rows you are looking at. `tail()` has the same shortcoming, although in that case figuring out the row numbers yourself is easier.