Add new column to GeoTable from Vector

Hey guys, new to Julia

I’ve searched so much and can’t seem to find an answer to this simple question..

How do I take a Vector, and add it as a new column to a GeoTable?

I see there is a way to create a new column (@transform(data, :col = value)), but this puts value into all rows of data. I want the Julia equivalent of R’s:

data$col <- value

The context is that I am working on some spatial function like GWR, and want to plot the spatial data with an intermediate Vector data from halfway through the function. I want to add the Vector data to the original GeoTable data (both are ordered correctly), and then plot it to get an idea of if the spatial function is displaying any strange behaviour.

Thanks!

Hi @beppi , thank you for sharing the question.

The @transform macro broadcasts the expression, meaning the right hand side of the equal sign is interpreted as a scalar value or a function call that will be applied to a vector of values. If you can share a MWE, I can help adjusting it for you.

We wish we had a simpler method to add and mutate the GeoTable columns, but that depends on Tables.jl adding support for setindex methods:

1 Like

One alternative is to use hcat to append columns in a second geotable over the same domain:

julia> t = georef((a=rand(10,10), b=rand(10,10)))
100×3 GeoTable over 10×10 CartesianGrid
┌────────────┬────────────┬─────────────────────────────────────────────────────────────┐
│     a      │     b      │                          geometry                           │
│ Continuous │ Continuous │                         Quadrangle                          │
│ [NoUnits]  │ [NoUnits]  │                    🖈 Cartesian{NoDatum}                     │
├────────────┼────────────┼─────────────────────────────────────────────────────────────┤
│  0.333049  │  0.225825  │ Quadrangle((x: 0.0 m, y: 0.0 m), ..., (x: 0.0 m, y: 1.0 m)) │
│  0.883544  │ 0.0195454  │ Quadrangle((x: 1.0 m, y: 0.0 m), ..., (x: 1.0 m, y: 1.0 m)) │
│  0.237656  │  0.323605  │ Quadrangle((x: 2.0 m, y: 0.0 m), ..., (x: 2.0 m, y: 1.0 m)) │
│ 0.0595238  │  0.719109  │ Quadrangle((x: 3.0 m, y: 0.0 m), ..., (x: 3.0 m, y: 1.0 m)) │
│  0.336137  │  0.804514  │ Quadrangle((x: 4.0 m, y: 0.0 m), ..., (x: 4.0 m, y: 1.0 m)) │
│  0.950602  │  0.201641  │ Quadrangle((x: 5.0 m, y: 0.0 m), ..., (x: 5.0 m, y: 1.0 m)) │
│  0.174771  │  0.948179  │ Quadrangle((x: 6.0 m, y: 0.0 m), ..., (x: 6.0 m, y: 1.0 m)) │
│  0.441083  │  0.916776  │ Quadrangle((x: 7.0 m, y: 0.0 m), ..., (x: 7.0 m, y: 1.0 m)) │
│  0.998553  │  0.617604  │ Quadrangle((x: 8.0 m, y: 0.0 m), ..., (x: 8.0 m, y: 1.0 m)) │
│     ⋮      │     ⋮      │                              ⋮                              │
└────────────┴────────────┴─────────────────────────────────────────────────────────────┘
                                                                          91 rows omitted

julia> c = rand(100)
100-element Vector{Float64}:
 0.759762909560509
 0.8997931717498272
 0.18915208994273836
 0.8566582169308061
 0.19567703024115346
 0.46919774219117694
 0.8523343403569035
 ⋮
 0.903176123042081
 0.05117485106717701
 0.8946719843259158
 0.025298978908059988
 0.9109253234275069
 0.44359813008201976
 0.01729330819684116

julia> [t georef((; c), domain(t))]
100×4 GeoTable over 10×10 CartesianGrid
┌────────────┬────────────┬────────────┬─────────────────────────────────────────────────────────────┐
│     a      │     b      │     c      │                          geometry                           │
│ Continuous │ Continuous │ Continuous │                         Quadrangle                          │
│ [NoUnits]  │ [NoUnits]  │ [NoUnits]  │                    🖈 Cartesian{NoDatum}                     │
├────────────┼────────────┼────────────┼─────────────────────────────────────────────────────────────┤
│  0.333049  │  0.225825  │  0.759763  │ Quadrangle((x: 0.0 m, y: 0.0 m), ..., (x: 0.0 m, y: 1.0 m)) │
│  0.883544  │ 0.0195454  │  0.899793  │ Quadrangle((x: 1.0 m, y: 0.0 m), ..., (x: 1.0 m, y: 1.0 m)) │
│  0.237656  │  0.323605  │  0.189152  │ Quadrangle((x: 2.0 m, y: 0.0 m), ..., (x: 2.0 m, y: 1.0 m)) │
│ 0.0595238  │  0.719109  │  0.856658  │ Quadrangle((x: 3.0 m, y: 0.0 m), ..., (x: 3.0 m, y: 1.0 m)) │
│  0.336137  │  0.804514  │  0.195677  │ Quadrangle((x: 4.0 m, y: 0.0 m), ..., (x: 4.0 m, y: 1.0 m)) │
│  0.950602  │  0.201641  │  0.469198  │ Quadrangle((x: 5.0 m, y: 0.0 m), ..., (x: 5.0 m, y: 1.0 m)) │
│  0.174771  │  0.948179  │  0.852334  │ Quadrangle((x: 6.0 m, y: 0.0 m), ..., (x: 6.0 m, y: 1.0 m)) │
│  0.441083  │  0.916776  │  0.467469  │ Quadrangle((x: 7.0 m, y: 0.0 m), ..., (x: 7.0 m, y: 1.0 m)) │
│  0.998553  │  0.617604  │  0.824009  │ Quadrangle((x: 8.0 m, y: 0.0 m), ..., (x: 8.0 m, y: 1.0 m)) │
│     ⋮      │     ⋮      │     ⋮      │                              ⋮                              │
└────────────┴────────────┴────────────┴─────────────────────────────────────────────────────────────┘
                                                                                       91 rows omitted

That is extremely verbose, but you can create a helper function:

addcolumn(t, c) = [t georef((; c), domain(t))]

What we really need to do is push the Tables.jl interface forward to include a setindex! api. The maintainers of the interface are not very responsive, unfortunately:

2 Likes

Thanks so much for your prompt replies, the code you provided is a perfect MWE (thanks!) for my case.

Your solution works, but I managed another solution:

new_t = @transform(t, :col = 0.0)
new_t.col .= c

Thanks again. I can see you’ve been fighting this fight for a while based on those linked issues haha.