# Creating one column from another

**URL:** <https://discourse.julialang.org/t/creating-one-column-from-another/86960>\
**Category:** New to Julia\
**Created:** [September 8, 2022, 7:28pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960 "2022-09-08T19:28:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nash](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nash/32/14482_2.png) [@Nash](https://discourse.julialang.org/u/Nash)\
**Post date:** [September 8, 2022, 7:28pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960/1 "2022-09-08T19:28:34Z")

</div>

Suppose I have a dataframe column (or a vector) with a sequence of numbers ranging from 1 to 4 (for example). Suppose also that a second column or vector must be constructed in the following way:

The new column has a 3, say, in a particular row because that is the new number the first vector changes to after having been 4, say. So, for example:

Col1: [4, 4, 4, 3, 3, 1, 2, 2, 2]

would result in

Col2: [3, 3, 3, 1, 1, 2, NaN, NaN, NaN]

Not that the last three items are NaN because there is no information about what comes after 2.

My question is simply, what code in Julia finds Col2 in an efficient t way?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 8, 2022, 7:46pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960/2 "2022-09-08T19:46:12Z")

</div>

This should work

```julia
julia> using DataFramesMeta, ShiftedArrays;

julia> df = DataFrame(Col1 = [4, 4, 4, 3, 3, 1, 2, 2, 2]);

julia> df2 = @chain df begin
           unique(:Col1)
           @transform :Col2 = lead(:Col1)
       end
4×2 DataFrame
 Row │ Col1 Col2    
     │ Int64 Int64?  
─────┼────────────────
   1 │ 4 3
   2 │ 3 1
   3 │ 1 2
   4 │ 2 missing 

julia> leftjoin(df, df2, on = "Col1")
9×2 DataFrame
 Row │ Col1 Col2    
     │ Int64 Int64?  
─────┼────────────────
   1 │ 4 3
   2 │ 4 3
   3 │ 4 3
   4 │ 3 1
   5 │ 3 1
   6 │ 1 2
   7 │ 2 missing 
   8 │ 2 missing 
   9 │ 2 missing 

```

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [September 8, 2022, 7:54pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960/3 "2022-09-08T19:54:34Z")

</div>

Here is my attempt for a vector:

```julia
function f(c1)

        c2 = zeros(length(c1))

        c2[end] = prev = NaN

        for i in reverse(eachindex(c1[begin:end-1]))
                if c1[i] == c1[i+1]
                        c2[i] = prev
                else
                        c2[i] = prev = c1[i+1]
                end
        end

        return c2

end

c1 = [4, 4, 4, 3, 3, 1, 2, 2, 2]
f(c1) |> println

# [3.0, 3.0, 3.0, 1.0, 1.0, 2.0, NaN, NaN, NaN]

```

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [September 8, 2022, 8:15pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960/4 "2022-09-08T20:15:24Z")

</div>

Great solution! It assumes that values won’t be repeated after a streak has ended (e.g., [4, 4, 4, 3, 3, 1, 2, 2, 2, 1, 2, 3, 4]), but that should be safe to do, depending on the context.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 8, 2022, 8:17pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960/5 "2022-09-08T20:17:40Z")

</div>

True. Good catch.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 8, 2022, 9:09pm UTC](https://discourse.julialang.org/t/creating-one-column-from-another/86960/6 "2022-09-08T21:09:07Z")

</div>

The most straightforward solution, can be less efficient for very long streaks of equal values:

```julia
julia> col1 = [4., 4, 4, 3, 3, 1, 2, 2, 2]

julia> col2 = map(enumerate(col1)) do (i, x)
           ix = findnext(!=(x), col1, i)
           isnothing(ix) ? NaN : col1[ix]
       end
9-element Vector{Float64}:
   3.0
   3.0
   3.0
   1.0
   1.0
   2.0
 NaN
 NaN
 NaN

```
