# Using push! to add a new row of data

**URL:** <https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 29, 2022, 9:43pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519 "2022-08-29T21:43:42Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Leon6](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon6/32/205483_2.png) [@Leon6](https://discourse.julialang.org/u/Leon6)\
**Post date:** [August 29, 2022, 9:43pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/1 "2022-08-29T21:43:42Z")

</div>

What is the proper way of using push to add rows to an existing matrix? I keep getting errors for the below code:

```julia
LL = fill(NaN, (0,2));
for j ∈ 1:n #180
    for i ∈ 1:m #360
        push!(LL, [X[i,j], Y[i,j]]);
    end
end

```

Many thanks!

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [August 29, 2022, 10:20pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/2 "2022-08-29T22:20:42Z")

</div>

You can only push to vectors, but not to multi-dimensional arrays. (See for example here [Resize!(matrix) - #2 by StefanKarpinski](https://discourse.julialang.org/t/resize-matrix/2379/2) why it is this way.)

- If you really need to add rows dynamically, you could consider using a `Vector` of `Vectors`

```julia
LL = Vector{Float64}[]
push!(LL, [1.0, 2.0])

```

or maybe you could use [Introduction · DataFrames.jl](https://dataframes.juliadata.org/stable/) or [GitHub - JuliaArrays/ElasticArrays.jl: Resizeable multi-dimensional arrays for Julia](https://github.com/JuliaArrays/ElasticArrays.jl)

- If you only need to add a few rows/columns, you could use `vcat` or `hcat`. For example

```julia
LL = [X[:] Y[:]] # or hcat(X[:],Y[:]) or hcat(vec(X),vec(Y))

```

- If you know in advance how many rows you need, that is of course ideal and it can sometimes give great performance benefits.

```julia
LL = fill(NaN, n*m, 2) # or LL = Array{Float64}(undef, n*m, 2)
k = 1
for j ∈ 1:n #180
    for i ∈ 1:m #360
        LL[k, :] .= (X[i,j], Y[i,j])
        k += 1
    end
end

```

---

<div class="post-metadata">

**Author:** ![Leon6](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon6/32/205483_2.png) [@Leon6](https://discourse.julialang.org/u/Leon6)\
**Post date:** [August 29, 2022, 11:57pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/3 "2022-08-29T23:57:36Z")

</div>

Unfortunately, I got the errors as below:

```julia
LoadError: BoundsError: attempt to access 64800-element Vector{Vector{Float64}} at index [1:64800, 2]
Stacktrace:
 [1] throw_boundserror(A::Vector{Vector{Float64}}, I::Tuple{Base.Slice{Base.OneTo{Int64}}, Int64})
   @ Base ./abstractarray.jl:691
 [2] checkbounds
   @ ./abstractarray.jl:656 [inlined]
 [3] _getindex
   @ ./multidimensional.jl:838 [inlined]
 [4] getindex(::Vector{Vector{Float64}}, ::Function, ::Int64)
   @ Base ./abstractarray.jl:1218
 [5] top-level scope
   @ ~/Desktop/Julia_coding/A04_global_projection/XY.jl:41

```

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [August 30, 2022, 5:40am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/4 "2022-08-30T05:40:15Z")

</div>

Which method did you try, and can you show your code?

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [August 30, 2022, 6:24am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/5 "2022-08-30T06:24:13Z")

</div>

If it is ok to push columns instead, you can use [GitHub - JuliaArrays/ElasticArrays.jl: Resizeable multi-dimensional arrays for Julia](https://github.com/JuliaArrays/ElasticArrays.jl).

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [August 30, 2022, 7:51am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/6 "2022-08-30T07:51:01Z")

</div>

When you use

```julia
LL = Vector{Float64}[]
push!(LL, [1.0, 2.0])

```

you have to access the rows via `LL[1]` (first row) or `LL[1][2] ` first row, second element.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 30, 2022, 8:00am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/7 "2022-08-30T08:00:53Z")

</div>

Keep in mind that Julia arrays are ‘column-major’, so adding rows is highly disadvantageous. Can you change your data layout so that you are adding columns instead?

---

<div class="post-metadata">

**Author:** ![Leon6](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon6/32/205483_2.png) [@Leon6](https://discourse.julialang.org/u/Leon6)\
**Post date:** [August 30, 2022, 12:16pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/8 "2022-08-30T12:16:04Z")

</div>

```julia
LL = Vector{Float64}[]
push!(LL, [1.0, 2.0])

```

---

<div class="post-metadata">

**Author:** ![Leon6](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon6/32/205483_2.png) [@Leon6](https://discourse.julialang.org/u/Leon6)\
**Post date:** [August 30, 2022, 12:19pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/9 "2022-08-30T12:19:41Z")

</div>

That will work. All I need to do is to transpose the matrix after it is generated.

Is there an easier way to do so without relying on an external program package like “Elastic Arrays”? I mean in Matlab, it is as easy as `A = [A; B];`

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [August 30, 2022, 12:35pm UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/10 "2022-08-30T12:35:56Z")

</div>

It’s equally easy in Julia.

```julia
m = 360
n = 180
X = rand(m, n)
Y = rand(m, n)
LL = fill(NaN, (0,2));
for j ∈ 1:n #180
    for i ∈ 1:m #360
        LL = [LL; X[i, j] Y[i, j]]
    end
end

```

The performance of doing it this way is horrible but that’s the case for Matlab as well, or at least it was when I last used Matlab.

---

<div class="post-metadata">

**Author:** ![Leon6](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leon6/32/205483_2.png) [@Leon6](https://discourse.julialang.org/u/Leon6)\
**Post date:** [August 31, 2022, 12:53am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/11 "2022-08-31T00:53:50Z")

</div>

Does anyone know why the code below does not work? Thanks

```julia
m = 360
n = 180
X = rand(m, n)
Y = rand(m, n)

LL = fill(NaN, (0,2));
for j ∈ 1:n #180
    for i ∈ 1:m #360
        var = [X[i,j] Y[i,j]];
        global LL = reduce((x, y) -> cat(x, y; dims = 2), [LL, var]);
    end
end

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [August 31, 2022, 6:48am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/12 "2022-08-31T06:48:22Z")

</div>

Mostly because you try to concatenate along the wrong dimension. But there’s nothing you can gain by using `reduce` on two elements.

```julia
reduce((x, y) -> cat(x, y; dims = 2), [LL, var])

```

is just a more complicated way, with some amount of overhead, to write

```julia
cat(LL, var; dims = 2)

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 31, 2022, 7:16am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/13 "2022-08-31T07:16:27Z")

</div>

Or just using concatenation syntax directly:

```julia
[LL var] # cat along dim 2
[LL; var] # cat along dim 1

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 31, 2022, 7:18am UTC](https://discourse.julialang.org/t/using-push-to-add-a-new-row-of-data/86519/14 "2022-08-31T07:18:30Z")

</div>

> [@Leon6](#):
>
> `global LL `

BTW, using `global` is discouraged (in all programming languages, not just Julia). Instead, you can put your code inside a function.

Here’s one way:

```julia
function mycat(X, Y)
    LL = similar(X, 0, 2)
    for i in eachindex(X, Y)
        LL = [LL; [X[i] Y[i]]]
    end
    return LL
end

```

But here’s a much better way:

```julia
function mycat2(X, Y)
    LL = similar(X, length(X), 2)
    for i in eachindex(X, Y)
        LL[i, 1] = X[i]
        LL[i, 2] = Y[i]
    end
    return LL
end

```

The last one is 200.000 times faster, and runs in 80us instead of 16 seconds.
