# Transpose of an array of Strings

**URL:** <https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431>\
**Category:** New to Julia\
**Tags:** strings, arrays\
**Created:** [May 29, 2020, 5:26pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431 "2020-05-29T17:26:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 29, 2020, 5:26pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/1 "2020-05-29T17:26:46Z")

</div>

Consider the statement:

```julia
a = [1 2 3 4]

```

and its transpose `a'`, which generates a column vector.

Now do the same with strings:

```julia
b = ["a" "b" "c"]

```

and transpose it. I get the following error (which is very hard to believe, since `["a"; "b"; "c"]` works perfectly well.). I cannot transpose an array of symbols either.

```julia
 b'
Error showing value of type LinearAlgebra.Adjoint{Union{},Array{String,2}}:
ERROR: MethodError: no method matching adjoint(::String)
Closest candidates are:
  adjoint(::Missing) at missing.jl:100
  adjoint(::LightGraphs.DefaultDistance) at /Users/erlebach/.julia/packages/LightGraphs/siFgP/src/distance.jl:22
  adjoint(::Number) at number.jl:169
  ...
Stacktrace:
 [1] getindex at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/LinearAlgebra/src/adjtrans.jl:178 [inlined]
 [2] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::MIME{Symbol("image/svg+xml")}, ::LinearAlgebra.Adjoint{Union{},Array{String,2}}; max_swatches::Int64) at /Users/erlebach/.julia/packages/Colors/P2rUx/src/display.jl:122
 [3] show at /Users/erlebach/.julia/packages/Colors/P2rUx/src/display.jl:91 [inlined]
 [4] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::String, ::LinearAlgebra.Adjoint{Union{},Array{String,2}}) at ./multimedia.jl:109
 [5] displayinplotpane(::LinearAlgebra.Adjoint{Union{},Array{String,2}}) at /Users/erlebach/.julia/packages/Atom/9h5Up/src/display/showdisplay.jl:67
 [6] display(::Atom.JunoDisplay, ::LinearAlgebra.Adjoint{Union{},Array{String,2}}) at /Users/erlebach/.julia/packages/Atom/9h5Up/src/display/showdisplay.jl:118
 [7] display(::Any) at ./multimedia.jl:323
 [8] #invokelatest#1 at ./essentials.jl:712 [inlined]
 [9] invokelatest at ./essentials.jl:711 [inlined]
 [10] print_response(::IO, ::Any, ::Bool, ::Bool, ::Any) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:161
 [11] print_response(::REPL.AbstractREPL, ::Any, ::Bool, ::Bool) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:146
 [12] (::REPL.var"#do_respond#38"{Bool,Atom.var"#250#251",REPL.LineEditREPL,REPL.LineEdit.Prompt})(::Any, ::Any, ::Any) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:729
 [13] #invokelatest#1 at ./essentials.jl:712 [inlined]
 [14] invokelatest at ./essentials.jl:711 [inlined]
 [15] run_interface(::REPL.Terminals.TextTerminal, ::REPL.LineEdit.ModalInterface, ::REPL.LineEdit.MIState) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/LineEdit.jl:2354
 [16] run_frontend(::REPL.LineEditREPL, ::REPL.REPLBackendRef) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:1055
 [17] run_repl(::REPL.AbstractREPL, ::Any) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:206
 [18] (::Base.var"#764#766"{Bool,Bool,Bool,Bool})(::Module) at ./client.jl:383
 [19] #invokelatest#1 at ./essentials.jl:712 [inlined]
 [20] invokelatest at ./essentials.jl:711 [inlined]
 [21] run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool) at ./client.jl:367
 [22] exec_options(::Base.JLOptions) at ./client.jl:305
 [23] _start() at ./client.jl:484

```

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 29, 2020, 5:53pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/3 "2020-05-29T17:53:53Z")

</div>

I have found that one can use the function ‘permutedims’ to accomplish the task. I do not know why one could not simply overload the transpose function (or the apostrophy operator) via dispatch? I assume that `transpose` is a more efficient version of `permutedims` that is optimized for `Numbers`.

In the end, here is some code I wrote related to the question asked. All is solved, although there is probably a more elegant way to accomplish this. I appreciate all the help.

```julia
prob_ode = ODEProblem(households!,u0,tspan,params);
sol_ode = solve(prob_ode, Tsit5());
df_ode = DataFrame(sol_ode(t)')
df_ode[!,:t] = t;

# Extract subsets of DataFrame
nb_save = 7
df_S = df_ode[!, 0*nb_houses+1 : 0*nb_houses+nb_save];
df_I = df_ode[!, 1*nb_houses+1 : 1*nb_houses+nb_save];
df_R = df_ode[!, 2*nb_houses+1 : 2*nb_houses+nb_save];
df_S[!,:t] = df_ode[!,:t];
df_I[!,:t] = df_ode[!,:t];
df_R[!,:t] = df_ode[!,:t];

nb_kept = 4;

# Put each state in its own database
function plotDF(dfr, state)
	labels=[];
	for i in 1:nb_kept push!(labels, "S"*repr(i) ) end
	@df dfr plot(:t,
    	cols([1:nb_kept]),
		label=permutedims(labels),
    	xlabel="Time",
    	ylabel="Number Susceptibles")
end

plotDF(df_S, "S")
plotDF(df_I, "I")
plotDF(df_R, "R")
```

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [May 29, 2020, 6:02pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/4 "2020-05-29T18:02:14Z")

</div>

The difference is that `transpose` (and `adjoint`, i.e. complex-conjugate transpose, which is what `'` does), are recursive, so if you have a vector of matrices, you end up with a row vector of transposed matrices. On the other hand, `permutedims` is not recursive. I don’t know all the details but I think this came about because one needed a way to do each thing (recursive and non-recursive) and it was decided that recursive transpose is a linear-algebraic operation, and thus suited for arrays of numbers, while `permutedims` is a data-storage operation.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [May 29, 2020, 6:02pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/5 "2020-05-29T18:02:38Z")

</div>

I think the point is that `'` produces an adjoint, which isn’t really a concept that exists for vectors of strings?

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 29, 2020, 6:12pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/6 "2020-05-29T18:12:55Z")

</div>

Transpose does not do complex conjugation, whereas adjoint does. And the “'” operator is a synonym for adjoint.  
However, Transpose does not work for 1D string arrays, although it is recursive, as is adjoint.  
It is still not clear why transpose would not work for strings.

---

<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:** [May 29, 2020, 6:17pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/7 "2020-05-29T18:17:22Z")

</div>

> [@erlebach](#):
>
> It is still not clear why transpose would not work for strings.

Do you have a suggestion for what the output of

```julia
julia> transpose("abc")

```

should be, and how it would make sense?

---

<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:** [May 29, 2020, 6:28pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/8 "2020-05-29T18:28:05Z")

</div>

Also, don’t you really want a `vector`? In which case I think the best practice is `vec(x)` or `reshape(x, :)`.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 29, 2020, 6:28pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/9 "2020-05-29T18:28:43Z")

</div>

Well, the transpose acts on an Array, and “abc” is not an array.

`Transpose(3)` returns `3`, so I would expect `transpose("abc")` to return “abc”.

However, [“abc”, “def”] is an array. So I would expect the transpose to return [“abc” “def”] just as `transpose([3,4])` returns `[3 4]`.  
I also checked the type hierarchy, and I do not believe that Array appears anywhere between String and Any.

What am I missing?

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 29, 2020, 6:35pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/10 "2020-05-29T18:35:50Z")

</div>

Why do I want to use a vector? What is the difference between a vector and a 1D Array? I thought it was a shortcut.

---

<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:** [May 29, 2020, 6:45pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/11 "2020-05-29T18:45:20Z")

</div>

```julia
julia> x = ["a string" "another string"]
1×2 Array{String,2}:
 "a string" "another string"

julia> permutedims(x)
2×1 Array{String,2}:
 "a string"
 "another string"

```

Notice that the result is still a `Array{String, 2}`, which is not a `Vector` i.e. `Array{String, 1}`

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [May 29, 2020, 6:47pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/12 "2020-05-29T18:47:45Z")

</div>

`transpose` and `adjoint` are linear algebra operations. If you want to treat your array as a container, use the container operations like `reshape`, `vec` or `permutedims`.

As far as the _why_ goes, the answer is that LinearAlgebra wants to support matrices of matrices and not all LinearAlgebra objects are themselves `::AbstractArray`s — so defaulting to a no-op is subtly error prone and defining a bunch of no-op transposes one-by-one is unsatisfactory. I’m not the biggest fan of this myself, but it is what it is.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 29, 2020, 6:56pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/13 "2020-05-29T18:56:23Z")

</div>

I have no qualms about “how it is” as long as it is documented. In order to improve my julia programming skills, I find it important to better understand the “why” of certain decisions, which will lead to improved program efficiency by making correct programming choices more often. Thanks for all your input!

Gordon

---

<div class="post-metadata">

**Author:** ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)\
**Post date:** [May 30, 2020, 1:49am UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/14 "2020-05-30T01:49:43Z")

</div>

> [@erlebach](#):
>
> In order to improve my julia programming skills, I find it important to better understand the “why” of certain decisions, which will lead to improved program efficiency by making correct programming choices more often.

Good on you. I’ve read [this issue](https://github.com/JuliaLang/julia/issues/4774) through a couple of times for the same reason. Still don’t totally understand all of it (linear algebra is not my first language), but I’ve learned a bunch!

---

<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:** [May 31, 2020, 9:33pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/15 "2020-05-31T21:33:29Z")

</div>

> [@erlebach](#):
>
> Well, the transpose acts on an Array, and “abc” is not an array.
> 
> `Transpose(3)` returns `3` , so I would expect `transpose("abc")` to return “abc”.

I think `transpose(scalar) = scalar` makes sense. But a string is a collection, not a scalar, so I don’t think that really works. At the same time it’s not an array. I actually think throwing an error makes sense here.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [May 31, 2020, 10:01pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/16 "2020-05-31T22:01:46Z")

</div>

Looks like your link didn’t copy-paste correctly.

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 31, 2020, 10:02pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/17 "2020-05-31T22:02:21Z")

</div>

Why not soulmate that the transpose of a collection is a collection?  
So, transpose (1:5) should return 1:5.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 31, 2020, 10:12pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/18 "2020-05-31T22:12:59Z")

</div>

Because then what you have is an identity function…

---

<div class="post-metadata">

**Author:** ![erlebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/erlebach/32/12973_2.png) [@erlebach](https://discourse.julialang.org/u/erlebach)\
**Post date:** [May 31, 2020, 10:24pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/19 "2020-05-31T22:24:45Z")

</div>

True, and whatmis wrong with that? If no harm done, why throw an error? For example, what if I take the transpose of [1:4, 2:6]? I would expect that to work.  
Isn’t the transposemofma scalar an identity operator? Why isn’t that a concern?  
The transposemofma diagonal matrixmis an identity operator. I have not checked, but I doubt an error exception is thrown.

I am new to Julia, so I might be missing something philosophically.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 31, 2020, 10:35pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/20 "2020-05-31T22:35:49Z")

</div>

The thing you’re missing is that `julia> 1:5 == [1,2,3,4,5]`. Collections are kind of by definition not scalars.

---

<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:** [May 31, 2020, 10:44pm UTC](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431/21 "2020-05-31T22:44:52Z")

</div>

> [@erlebach](#):
>
> So, transpose (1:5) should return 1:5.

`1:5` is a vector, so transposing that returns a transposed vector, similar to a row vector (isomorphic is the word, I think). It would be bad if

```julia
(1:5)' * A

```

suddenly stopped working for appropriately sized matrices. Ranges are AbstractVectors and need to behave accordingly.

[Next page](https://discourse.julialang.org/t/transpose-of-an-array-of-strings/40431.md?page=2)
