# Elegant way to handle columns operations

Inspired by this question from @sjdh and by my recurrent use of columns operations in database sets, I was looking for one way to make columns operations more symetric, so I can handle with matrix and lists in a more clean way when working with this kind of data.

For instance, I think it's not very practical to append a list data to a matrix using Join[matA, {colA} // Transpose, 2] or prepend using Prepend[Transpose@matA, colA] // Transpose. It's very clumsy, but we get used to it (I realized that teaching to a friend).

I created this function called colAppend, that I would like to share here, and ask for performance tuning, tips on code organization and maybe another combinations of row operations that I have missed.

Here are our test matrix and lists:

matA={{mA1,mA2},{mA3,mA4},{mA5,mA6}};
matB={{mB1,mB2},{mB3,mB4},{mB5,mB6}};
colA={cA1,cA2,cA3};
colB={cB1,cB2,cB3};


Now there are the function colAppend definitions. I separated it in 3 blocks:

1- Basic Join Operations

colAppend[mat1_,mat2_]/;(Length@Dimensions@mat1>1&&Length@Dimensions@mat2>1):=
Join[mat1,mat2,2]

colAppend[mat1_,col1_,pos_:-1]/;(Length@Dimensions@mat1>1&&Length@Dimensions@col1==1):=
Insert[mat1//Transpose, col1, pos]//Transpose

colAppend[col1_,col2_]/;(Length@Dimensions@col1==1&&Length@Dimensions@col2==1):=
Transpose[{col1,col2}]

colAppend[col1_,mat1_,pos_:1]/;(Length@Dimensions@col1==1&&Length@Dimensions@mat1>1):=
Insert[mat1//Transpose, col1, pos]//Transpose

colAppend[colA,matA]//MatrixForm
colAppend[colA,colB]//MatrixForm
colAppend[matA,matB]//MatrixForm
colAppend[matA,colA]//MatrixForm


2- Deleting Columns

Maybe it could be another function colDelete, so we could remove the Null parameter.

colAppend[mat1_,Null,pos_:-1]/;(Length@Dimensions@mat1>1):=
Module[{temp=mat1},
temp[[All,pos]]=Sequence[];
temp
]

colAppend[Null,mat1_,pos_:1]/;(Length@Dimensions@mat1>1):=
Module[{temp=mat1},
temp[[All,pos]]=Sequence[];
temp
]

colAppend[matA,Null]//MatrixForm
colAppend[Null,matA]//MatrixForm


3- Join Multiple Elements

Combine all the above function (with except Null one)

colAppend::badargs = "Incompatible Dimensions";
colAppend[args__]:=Module[{list=List[args]},
Fold[colAppend,First@list,Rest@list]
]

MatrixForm@colAppend[matA,colA,matB,colB]


What another functionality I'm missing?

What is the best way to create such function?

Update 1

As VLC has posted in the comments. For part 3, this answer from @Mr.Wizard is the best option, not just in simplicity, but in performance too!

columnAttach2[ak__List]:=Replace[Unevaluated@Join[ak,2],v_?VectorQ:>{v}\[Transpose],1]

-
– VLC Feb 2 '13 at 18:48
@VLC Hi. Interesting link. Will study that. Tks – Murta Feb 2 '13 at 18:57

After some time looking for how to handler that question, I get into this set of function, that I have added to my tool-bag. The first one (colAttach) is from @Mr.Wizard.

colAttach[ak__List]:=Replace[Unevaluated@Join[ak,2],v_?VectorQ:>{v}\[Transpose],1]

colInsert[mat1_?MatrixQ,col1_?VectorQ,pos_:-1]:=Insert[mat1//Transpose, col1, pos]//Transpose
colInsert[mat1_?MatrixQ,mat2_?MatrixQ,pos_:-1]:=Insert[mat1//Transpose, mat2, pos]//Transpose//Flatten[#,1]&/@#&

colDelete[mat1_?MatrixQ,pos_:-1]:=Module[{r},
r=mat1;
r[[All,pos]]=Sequence[];
r
]

colPermute[mat_List?MatrixQ,permCicle_List]:=Module[{r=mat,permute},
Scan[(r[[All,#]]=r[[All,Reverse@#]])&,If[VectorQ[permCicle],{permCicle},permCicle]];
r
]


The use of the first 3 (colAttach, colInsert and colDelete) works just as stated in the question.

The last one (colPermute) use the structure.

matA = {{mA1, mA2, mA3}, {mA1, mA2, mA3}, {mA1, mA2, mA3}};
mrtColPermute[matA, {1, 2}] // MatrixForm
mrtColPermute[matA, {{1, 2}, {3, 1}}] // MatrixForm


-

As already noted the column append part of this question is answered here.

colDelete is already implemented as Drop, though you could tweak the syntax if you desire:

a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

Drop[a, None, {2}]

{{1, 3}, {4, 6}, {7, 9}}


Insert was asked about on StackOverflow: How to insert a column into a matrix, the correct Mathematica way

The double Transpose was the best method found.

-