# How to correctly create ''slices'' of a column by using indexes of another one, in a DataFrame

**URL:** <https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245>\
**Category:** New to Julia\
**Tags:** dataframes\
**Created:** [November 14, 2022, 3:55pm UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245 "2022-11-14T15:55:56Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Juan\_Mac\_Donagh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan_mac_donagh/32/31798_2.png) [@Juan\_Mac\_Donagh](https://discourse.julialang.org/u/Juan_Mac_Donagh)\
**Post date:** [November 14, 2022, 3:55pm UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/1 "2022-11-14T15:55:56Z")

</div>

Hi all, I have a question regarding how to correctly solve this:

I have a `DataFrame` that has the following columns:

```julia
df.i1 = [[1,2,3,4,5,1,2],[1,2,3,4,5,6,8,10,11],[1,2,3,4,5]]
df.i2 = [[4,2,1],[3,3,3],[1,2,2]]

```

And I need to generate three new columns, that have the values from `df.i1` using the indexes from `df.i2`, so the result should be something like this: following `df.i1`, the first slice for the first item should go from 1 to 4, the following one from `4+1` to `4+2`, and the last one from `4+2+1` to `4+2+1` (which is also the total length of the sequence, as `df.i2` is generated by using the `rle` function in another column)

```julia
df.v1 = [[1,2,3,4],[1,2,3],[1]]

df.v2 = [[5,1],[4,5,6],[2,3]]

df.v3 = [[2],[8,10,11],[4,5]]

```

So far I tried using something like this:

```julia
for i in eachrow(df)

		mi = i.i[1]

		df_a.v1 = [x[1:mi] for x in i.zeros]
		
end

```

That can be extended to the other two cases, but I am getting the following error:

```julia
MethodError: no method matching getindex(::Int64, ::UnitRange{Int64})

```

Any help is welcome, I suppose that I am on the right track by looping over the rows of the df and trying to generate the slices that way, but I might be wrong.

Thanks!  
Cheers.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [November 14, 2022, 5:49pm UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/3 "2022-11-14T17:49:45Z")

</div>

I’m not sure I understand your description, and I’m on my phone so I can’t check if this works, but maybe

```julia
transform!(df, 
    (:i1,:i2) => ((i1, i2) -> [i1[1:i] for i in i2]) => :v3
)

```

Even if this isn’t quite the solution, maybe it will help you come up with an answer – `transform!()` is for adding new columns to a dataframe.

The second line does the following steps.

1. Selects input columns
2. Applies an anonymous function to each row of the input columns
3. Saves the output to the final vector name.

Note: You can’t use `:v3` in subsequent transformations within the same `transform!()` call. You need to call it again on `df` if you want to use `:v3` as an input in addition transformations.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 14, 2022, 6:17pm UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/4 "2022-11-14T18:17:36Z")

</div>

Is this what you want?

```julia
julia> df
3×2 DataFrame
 Row │ i1 i2
     │ Array… Array…
─────┼──────────────────────────────────────────
   1 │ [1, 2, 3, 4, 5, 1, 2] [4, 2, 1]
   2 │ [1, 2, 3, 4, 5, 6, 8, 10, 11] [3, 3, 3]
   3 │ [1, 2, 3, 4, 5] [1, 2, 2]

julia> function cutv(x,idx)
           ends = cumsum(idx)
           starts = [1; ends[1:end-1] .+ 1]
           return [x[s:e] for (s,e) in zip(starts, ends)]
       end
cutv (generic function with 1 method)

julia> function trans(xs, idxs)
           newvs = [cutv(xs[i], idxs[i]) for i in eachindex(xs, idxs)]
           return [[v[i] for v in newvs] for i in eachindex(newvs...)]
       end
trans (generic function with 1 method)

julia> df.v1, df.v2, df.v3 = trans(df.i1, df.i2);

julia> df
3×5 DataFrame
 Row │ i1 i2 v1 v2 v3
     │ Array… Array… Array… Array… Array…
─────┼────────────────────────────────────────────────────────────────────────────────
   1 │ [1, 2, 3, 4, 5, 1, 2] [4, 2, 1] [1, 2, 3, 4] [5, 1] [2]
   2 │ [1, 2, 3, 4, 5, 6, 8, 10, 11] [3, 3, 3] [1, 2, 3] [4, 5, 6] [8, 10, 11]
   3 │ [1, 2, 3, 4, 5] [1, 2, 2] [1] [2, 3] [4, 5]

```

---

<div class="post-metadata">

**Author:** ![Juan\_Mac\_Donagh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan_mac_donagh/32/31798_2.png) [@Juan\_Mac\_Donagh](https://discourse.julialang.org/u/Juan_Mac_Donagh)\
**Post date:** [November 15, 2022, 8:53am UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/5 "2022-11-15T08:53:14Z")

</div>

Yes!! Both functions worked perfectly, thanks. I will try to get my head around both functions, as I’m not really sure I understand the second one.

Thanks again!  
Juan

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 15, 2022, 10:10am UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/6 "2022-11-15T10:10:36Z")

</div>

You mean in my solution.  
The process is:

1. in `cutv` we cut individual `i1` vectors using the `i2` information.
2. in `trans` we first create `newvs` that cuts all vectors in `i1`, next we rearrange vector of vectors the way you want.

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [November 16, 2022, 5:55pm UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/7 "2022-11-16T17:55:19Z")

</div>

Another version of `cutv` function which takes iterators instead of vectors.

Perhaps some other tinkerer can make it more compact/Julian/faster:

```julia
julia> cutitr(itr1,itr2) = last(
         foldl(
           (s,t)->(
             (r1, e1) = foldl( (x,y)->( 
               (e,r) = Iterators.peel(x[1]) ; 
               (r, push!(x[2],e))
             ), 1:t ; init=(s[1], Int[]) ) ; 
             (r1, push!(s[2], e1)) 
           ), itr2 ; init=(itr1,Vector{Int}[])
         )
       )
cutitr (generic function with 1 method)

julia> cutitr(i1,i2)
3-element Vector{Vector{Int64}}:
 [1, 2, 3, 4]
 [5, 1]
 [2]

julia> cutitr(i1,i2) == cutv(i1,i2)
true

```

(it takes about 1.4x slower than vector version on my machine)

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [November 16, 2022, 6:12pm UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/8 "2022-11-16T18:12:52Z")

</div>

Nice. I did not optimize my code for speed/allocations but for being easy to understand 😄 (but appreciate the “need for speed”).

---

<div class="post-metadata">

**Author:** ![Juan\_Mac\_Donagh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan_mac_donagh/32/31798_2.png) [@Juan\_Mac\_Donagh](https://discourse.julialang.org/u/Juan_Mac_Donagh)\
**Post date:** [November 17, 2022, 8:25am UTC](https://discourse.julialang.org/t/how-to-correctly-create-slices-of-a-column-by-using-indexes-of-another-one-in-a-dataframe/90245/9 "2022-11-17T08:25:32Z")

</div>

Nice!! I can tell that this one es faster, only because the code took me a while to understand haha. If my data becomes bigger, I will switch to this version. Thanks!!  
Best,
