# How to dispatch a function aggregating columns in a grouped DataFrame?

**URL:** <https://discourse.julialang.org/t/how-to-dispatch-a-function-aggregating-columns-in-a-grouped-dataframe/60859>\
**Category:** General Usage\
**Tags:** dataframes\
**Created:** [May 10, 2021, 8:19am UTC](https://discourse.julialang.org/t/how-to-dispatch-a-function-aggregating-columns-in-a-grouped-dataframe/60859 "2021-05-10T08:19:13Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![florian](https://avatars.discourse-cdn.com/v4/letter/f/898d66/32.png) [@florian](https://discourse.julialang.org/u/florian)\
**Post date:** [May 10, 2021, 8:19am UTC](https://discourse.julialang.org/t/how-to-dispatch-a-function-aggregating-columns-in-a-grouped-dataframe/60859/1 "2021-05-10T08:19:13Z")

</div>

I want to aggregate the columns of a DataFrame based on their types, i.e something like:

```julia
function aggregate(v::Vector{T}) where T <: Number
    sum(v)
end

function aggregate(v::Vector{String})
    [unique(v)]
end

df = DataFrame(idx = [1, 2, 3], a = [10, 20, 30], b = ["text1", "text2", "text3"]);
test1 = combine(df, names(df) .=> aggregate)
test2 = combine(groupby(df, :idx), names(df) .=> aggregate)

```

What is the best way to make this work for the grouped DataFrame? The columns don’t seem to be simple vectors after applying `groupby`, but some kind of `SubArray`. What’s the cleanest way to make custom functions work for those types?

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [May 10, 2021, 9:14am UTC](https://discourse.julialang.org/t/how-to-dispatch-a-function-aggregating-columns-in-a-grouped-dataframe/60859/3 "2021-05-10T09:14:27Z")

</div>

Indeed it gets called with a SubArray. I don’t think that’s documented, but it’s a bit of an implementation detail… You have for example:

```julia
julia> SubArray{String, 1, Vector{String}, Tuple{Vector{Int64}}, false} <: AbstractVector{String}
true

```

so you can define:

```julia
function agg(v::AbstractVector{<:Number})
   sum(v)
end

function agg(v::AbstractVector{String})
   [unique(v)]
end

```

This works:

```julia
using DataFrames

df = DataFrame(idx = [1, 2, 3], a = [10, 20, 30], b = ["text1", "text2", "text3"]);

julia> test1 = combine(df, names(df) .=> agg)
1×3 DataFrame
 Row │ idx_agg a_agg b_agg                       
     │ Int64 Int64 Array…                      
─────┼─────────────────────────────────────────────
   1 │ 6 60 ["text1", "text2", "text3"]

julia> test2 = combine(groupby(df, :idx), names(df) .=> agg)
3×4 DataFrame
 Row │ idx idx_agg a_agg b_agg     
     │ Int64 Int64 Int64 Array…    
─────┼──────────────────────────────────
   1 │ 1 1 10 ["text1"]
   2 │ 2 2 20 ["text2"]
   3 │ 3 3 30 ["text3"]

```

although in typical usage you can do directly:

```julia
julia> test2 = combine(groupby(df, :idx), names(df, Number) .=> sum, names(df, String) .=> Ref∘unique)
3×4 DataFrame
 Row │ idx idx_sum a_sum b_Ref_unique 
     │ Int64 Int64 Int64 Array…       
─────┼─────────────────────────────────────
   1 │ 1 1 10 ["text1"]
   2 │ 2 2 20 ["text2"]
   3 │ 3 3 30 ["text3"]

```
