# Vector to NamedTuple?

**URL:** <https://discourse.julialang.org/t/vector-to-namedtuple/20683>\
**Category:** General Usage\
**Created:** [February 11, 2019, 9:17pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683 "2019-02-11T21:17:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![goedman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goedman/32/217_2.png) [@goedman](https://discourse.julialang.org/u/goedman)\
**Post date:** [February 11, 2019, 9:17pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/1 "2019-02-11T21:17:43Z")

</div>

Hi, there are good examples to convert NamedTupes to Dict and vice versa etc. But in e.g. Optim’s minimize, I would like to go from a single vector to a NamedTuple.I was wondering if this case has a proven solution?

I came up with:

```julia
function vec2nt(v::Vector, nt::T) where {T <: NamedTuple}
  pv = Vector{UnitRange{Int64}}(undef, length(nt))
  indx = 0; start = 1
  for key in keys(nt)
    indx += 1
    pv[indx] = start:start-1+length(nt[key])
    start = start+length(nt[key])
  end
  println(pv)
  t = [v[pv[i]] for i in 1:length(pv)]
  nnt =NamedTuple{keys(nt), typeof(values(nt))}(t)
end

v = [6,7,8,9,10, 11, 12]
nt = (a=[1, 2], b=[3,4,5], c=[6, 7])

vec2nt(v, nt)

```

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 11, 2019, 9:49pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/2 "2019-02-11T21:49:31Z")

</div>

How about just:

```julia
julia> v = [6,7,8,9,10,11,12];

julia> nt = (a=[1,2], b=[3,4,5], c=[6,7]);

julia> NamedTuple{keys(nt)}(map.(i -> v[i], values(nt)))
(a = [6, 7], b = [8, 9, 10], c = [11, 12])

```

Which has the added benefit of supporting non-consecutive and repeated indexes:

```julia
julia> nt = (a=[1,7], b=[5,4,3], c=[1,2,1,2]);

julia> NamedTuple{keys(nt)}(map.(i -> v[i], values(nt)))
(a = [6, 12], b = [10, 9, 8], c = [6, 7, 6, 7])

```

---

<div class="post-metadata">

**Author:** ![goedman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goedman/32/217_2.png) [@goedman](https://discourse.julialang.org/u/goedman)\
**Post date:** [February 11, 2019, 10:52pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/3 "2019-02-11T22:52:04Z")

</div>

Thank you. Close, but I should have provided more realistic inputs:

```julia
nt = (β = [1.0, 0.25], α = rand(10), s = [0.2])
v = (γ = vcat([1.0, 0.25], rand(10), [0.2]))
NamedTuple{keys(nt)}(map.(i -> v[i], values(nt)))

```

Your example does point to another solution though (using a NamedTuple with indices)!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 12, 2019, 8:49am UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/4 "2019-02-12T08:49:33Z")

</div>

> [@goedman](#):
>
> `nt = (β = [1.0, 0.25], α = rand(10), s = [0.2])`

```julia
julia> using TransformVariables

julia> trans = as((β = as(Array, 2), α = as(Array, 10), s = as(Array, 1)));

julia> nt = (β = [1.0, 0.25], α = rand(10), s = [0.2])
(β = [1.0, 0.25], α = [0.158498, 0.171848, 0.846386, 0.474491, 0.0255008, 0.681615, 0.695278, 0.704238, 0.895584, 0.368178], s = [0.2])

julia> y = inverse(trans, nt)
13-element Array{Float64,1}:
 1.0                 
 0.25                
 0.15849757451847424 
 0.17184825252678304 
 0.8463861675797599  
 0.4744913375760429  
 0.025500775432728107
 0.681615427076824   
 0.695277914515098   
 0.7042375146704107  
 0.8955843266165946  
 0.3681783642201166  
 0.2                 

julia> trans(y)
(β = [1.0, 0.25], α = [0.158498, 0.171848, 0.846386, 0.474491, 0.0255008, 0.681615, 0.695278, 0.704238, 0.895584, 0.368178], s = [0.2])

```

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [February 12, 2019, 1:25pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/5 "2019-02-12T13:25:24Z")

</div>

> [@goedman](#):
>
> Thank you. Close, but I should have provided more realistic inputs

You can use `foldl`:

```julia
julia> nt = (β = [1.0, 0.25], α = rand(10), s = [0.2])
(β = [1.0, 0.25], α = [0.750847, 0.722269, 0.117531, 0.690413, 0.804141, 0.539423, 0.150192, 0.705363, 0.975111, 0.365696], s = [0.2])

julia> (v = vcat([1.0, 0.25], rand(10), [0.2]))'
1×13 Adjoint{Float64,Array{Float64,1}}:
 1.0 0.25 0.372726 0.534158 0.408041 0.859988 0.099716 0.175659 0.459855 0.0935148 0.377641 0.924534 0.2

julia> NamedTuple{keys(nt)}(foldl(((a,i),b) -> (k=i+length(b);
           ((a...,v[i:k-1]), k)), values(nt); init=((),1))[1])
(β = [1.0, 0.25], α = [0.372726, 0.534158, 0.408041, 0.859988, 0.099716, 0.175659, 0.459855, 0.0935148, 0.377641, 0.924534], s = [0.2])

```

---

<div class="post-metadata">

**Author:** ![goedman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goedman/32/217_2.png) [@goedman](https://discourse.julialang.org/u/goedman)\
**Post date:** [February 12, 2019, 3:11pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/6 "2019-02-12T15:11:07Z")

</div>

Thank you Max and Tamas, both are nice solutions!

Tamas, you probably recognized the context of my question. I’m looking into ways of passing the problem - p(theta) - to Optim’s minimize to compute the maximum\_a\_posterior estimate. Slowly I’m unraveling the steps in the DynamicHMC ‘recipe’ I seem to be using over and over. And understanding the ‘as’ statement is on my list. Very neat.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 13, 2019, 10:10am UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/7 "2019-02-13T10:10:11Z")

</div>

> [@goedman](#):
>
> And understanding the ‘as’ statement is on my list. Very neat.

It’s probably not the ideal interface. I got really carried away with the possibility of nested transformations (eg a vector of `NamedTuples` of heterogeneous elements), but now I am of the opinion that in practice, a `NamedTuple`of `Array`s and scalars would do just fine (basically isomorphic to what is handled by, say, Stan). One would just specify the dimensions, eg

```julia
make_transformation((β = 2, α = 10, s = 1)) # hypothetical

```

that would just transform 13-element vectors to `NamedTuple`s like above.

Also, I plan to separate the vector deconstruction and the actual nonlinear transformation interface, and add `SArray`s etc. But I need to think more about this. Suggestions welcome!

---

<div class="post-metadata">

**Author:** ![goedman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goedman/32/217_2.png) [@goedman](https://discourse.julialang.org/u/goedman)\
**Post date:** [February 14, 2019, 3:31pm UTC](https://discourse.julialang.org/t/vector-to-namedtuple/20683/8 "2019-02-14T15:31:07Z")

</div>

Thank you Tamas! Not sure I can come up with actionable suggestions, but maybe it helps to explain what I found difficult to grasp. In:

```julia
problem_transformation(p::m_12_06d_model) =
    as( (β = as(Array, size(p.X, 2)), α = as(Array, p.N_societies), σ = asℝ₊) )

```

the σ component is a domain prescription while in above usage

```julia
make_transformation((β = 2, α = 10, s = 1)) # hypothetical

```

it is more like a direct mapping.

I noticed that when I try to use p(theta) in Optim.minimize indeed I have to play tricks with σ (i.e. square s to prevent it to go below 0). E.g. in [m12.6d1.jl](https://statisticalrethinkingjulia.github.io/DynamicHMCModels.jl/latest/12/m12.6d1/).

But that’s probably what you mean by your last sentence above. The transformation component can be directly specified in

```julia
P = TransformedLogDensity(problem_transformation(p), p)

```

There may be other reasons to use an intermediate function, but in simple cases, couldn’t it be a direct as()?
