# Creating custom DataFrame types

**URL:** <https://discourse.julialang.org/t/creating-custom-dataframe-types/4992>\
**Category:** Data\
**Tags:** question, data\
**Created:** [July 21, 2017, 12:26am UTC](https://discourse.julialang.org/t/creating-custom-dataframe-types/4992 "2017-07-21T00:26:02Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [July 21, 2017, 12:26am UTC](https://discourse.julialang.org/t/creating-custom-dataframe-types/4992/1 "2017-07-21T00:26:02Z")

</div>

I am putting some effort to include a special DataFrame type in my package that tracks columns representing spatial coordinates:

```julia
struct GeoData
  data::AbstractDataFrame
  coordnames::Vector{Symbol}
end

```

I can then define simple methods for it that just forward the arguments to the underlying DataFrame method:

```julia
function readtable(args...; coordnames=[:x,:y,:z], kwargs...)
  data = DataFrames.readtable(args...; kwargs...)
  GeoData(data, coordnames)
end

```

It works fine, but I was wondering if there is a better way of achieving this “inheritance” of methods automatically instead of typing them one by one. Is it possible to copy all the DataFrame API to the GeoData type in a safe manner?

In other words, if we adopt composition over inheritance, there is no hope for straightforward reuse of APIs?

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [July 21, 2017, 1:27am UTC](https://discourse.julialang.org/t/creating-custom-dataframe-types/4992/2 "2017-07-21T01:27:16Z")

</div>

Have you tried `struct GeoData <: AbstractDataFrame`? Then all you need to do (assuming there’s a well-defined one) is to implement the basic DataFrame interface your `GeoData` type, and all functions that 1) take an `AbstractDataFrame` and 2) use the interface should automatically work.

This is how we did it in MetaGraphs.

Also: you might reconsider your GeoData struct:

```julia
struct GeoData{T<:AbstractDataFrame} <: AbstractDataFrame
  data::T
  coordnames::Vector{Symbol}
end

```

This avoids having an abstract type as a field, which supposedly improves performance.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [July 21, 2017, 1:59am UTC](https://discourse.julialang.org/t/creating-custom-dataframe-types/4992/3 "2017-07-21T01:59:04Z")

</div>

Thank you @anon94023334, I think in this case I really need composition. It would be awesome to have the goodies of inheritance and basically mimic the behavior of a DataFrame with extra metadata automatically though. I am still getting used to these paradigms, need to read more about them.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [July 21, 2017, 4:30am UTC](https://discourse.julialang.org/t/creating-custom-dataframe-types/4992/4 "2017-07-21T04:30:16Z")

</div>

A similar topic was discussed here

> [@Wrap and inherit Number](https://discourse.julialang.org/t/wrap-and-inherit-number/4799):
>
> I’ve seen topics touching this in different constellations, but: How do people create a new type that would magically behave just like any subtype of (say) Number? So for example, if: struct A{T \<: Number} x::T end then I’d just be able to \*, +, sin, exp, or sqrt instances of A and on top of that I’d still be able to (re)define additional specialized methods like say sqrt(a::A) = (a.x)^(1/3)? Thanks and sorry for the overlap/repeat.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [July 21, 2017, 2:55pm UTC](https://discourse.julialang.org/t/creating-custom-dataframe-types/4992/5 "2017-07-21T14:55:46Z")

</div>

Thank you @baggepinnen, scanning that thread I found `TypedDelegation.jl`, which defines a set of very useful macros for this task. I will probably use it now. I hope it will be part of Base at some point.
