Function Repository Resource:

TransformTabular

Source Notebook

Transform simultaneously all columns of a tabular or a selection of them

Contributed by: Daniele Gregori

ResourceFunction["TransformTabular"][tab,f]

transforms all columns of a tabular through a single function.

ResourceFunction["TransformTabular"][tab,f,i;;j]

transforms a span of columns of a tabular through a single function.

ResourceFunction["TransformTabular"][tab,f,{col1,col2,}]

transforms a list of columns of a tabular through a single function.

ResourceFunction["TransformTabular"][f,{col1,col2,}]

represents the operator form of TransformTabular.

Details

Sometimes it can be convenient to perform a single operation simultaneously on a whole Tabular. ResourceFunction["TransformTabular"] allows one to do that, by applying a single function to all columns or a specified selection of them.
f is a function with generic Slot.
The optional third argument can be either a list of columns, or a list of column indexes, or a single column, or a Span.
ResourceFunction["TransformTabular"] acts as TransformColumns, when the same transformation is specified for each column.
ResourceFunction["TransformTabular"] also supports the operations of ColumnwiseValue and ColumnwiseThread.

Examples

Basic Examples (3) 

Given a simple tabular with many columns:

In[1]:=
tabInt = With[{cols = Alphabet[][[;; 10]]},
  Tabular[
   Table[AssociationThread[cols, Table[RandomInteger[100], Length@cols]], 4]]]
Out[1]=

We can simultaneously apply a mathematical function to all its elements:

In[2]:=
ResourceFunction["TransformTabular"][tabInt, N[Log[#^2 + 1]] &]
Out[2]=

Or change the colors of all cells with a given property:

In[3]:=
ResourceFunction["TransformTabular"][tabInt, If[EvenQ[#], Style[#, Red], #] &]
Out[3]=

Scope (6) 

Suppose some data science work produced errors in the final Tabular (as many Round[Missing[]] cells):

In[4]:=
tabData = 
Tabular[<|"RawSchema" -> <|"ColumnProperties" -> <|"Municipality" -> <|"ElementType" -> "String"|>, "2023" -> <|"ElementType" -> "InertExpression"|>, "2022" -> <|"ElementType" -> "InertExpression"|>, "2021" -> <|"ElementType" -> "InertExpression"|>, "2020" -> <|"ElementType" -> "InertExpression"|>, "2019" -> <|"ElementType" -> "InertExpression"|>, "2018" -> <|"ElementType" -> "InertExpression"|>, "2017" -> <|"ElementType" -> "Integer64"|>, "2016" -> <|"ElementType" -> "InertExpression"|>|>, "KeyColumns" -> {"Municipality"}, "Backend" -> "WolframKernel"|>,
     "BackendData" -> <|"ColumnData" -> DataStructure["ColumnTable", {{
TabularColumn[<|"Data" -> {{3, {0, 4, 12, 22, 41, 53, 60, 67, 74, 92, 103, 123, 132, 148, 162, 172, 178, 194, 205}, "AdroBerlingoCastegnatoCazzago San MartinoCorte FrancaErbuscoGussagoLogratoMonticelli BrusatiOspitalettoPaderno FranciacortaPassiranoProvaglio D'IseoRodengo-SaianoRoncadelleRovatoTorbole CasagliaTravagliato"}, {},
               None}, "ElementType" -> "String"|>], 
TabularColumn[<|"Data" -> {{210, 273, 1032, 
Round[
Missing[]], 78, 340, 282, 312, 256, 92, 479, 330, 
Round[
Missing[]], 602, 556, 392, 286, 243}, {}, None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {210, 273, 1032, 
Round[
Missing[]], 78, 340, 282, 312, 256, 92, 479, 330, 
Round[
Missing[]], 602, 556, 392, 286, 243}|>], 
TabularColumn[<|"Data" -> {{
Round[
Missing[]], 344, 1089, 273, 216, 386, 295, 449, 332, 367, 533, 489, 490, 641, 644, 
Round[
Missing[]], 424, 335}, {}, None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {
Round[
Missing[]], 344, 1089, 273, 216, 386, 295, 449, 332, 367, 533, 489, 490, 641, 644, 
Round[
Missing[]], 424, 335}|>], 
TabularColumn[<|"Data" -> {{194, 322, 
Round[
Missing[]], 248, 198, 374, 
Round[
Missing[]], 531, 400, 
Round[
Missing[]], 581, 304, 454, 540, 529, 385, 513, 441}, {}, None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {194, 322, 
Round[
Missing[]], 248, 198, 374, 
Round[
Missing[]], 531, 400, 
Round[
Missing[]], 581, 304, 454, 540, 529, 385, 513, 441}|>], 
TabularColumn[<|"Data" -> {{160, 342, 820, 454, 239, 447, 
Round[
Missing[]], 486, 492, 234, 392, 317, 423, 509, 344, 317, 563, 457}, {},
               None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {160, 342, 820, 454, 239, 447, 
Round[
Missing[]], 486, 492, 234, 392, 317, 423, 509, 344, 317, 563, 457}|>], 
TabularColumn[<|"Data" -> {{92, 246, 493, 271, 301, 405, 202, 417, 262, 1, 
Round[
Missing[]], 197, 271, 302, 
Round[
Missing[]], 277, 456, 351}, {}, None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {92, 246, 493, 271, 301, 405, 202, 417, 262, 1, 
Round[
Missing[]], 197, 271, 302, 
Round[
Missing[]], 277, 456, 351}|>], 
TabularColumn[<|"Data" -> {{152, 132, 444, 342, 335, 
Round[
Missing[]], 216, 480, 191, 35, 339, 178, 377, 242, 405, 315, 391, 380}, {}, None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {152, 132, 444, 342, 335, 
Round[
Missing[]], 216, 480, 191, 35, 339, 178, 377, 242, 405, 315, 391, 380}|>], 
TabularColumn[<|"Data" -> {{171, 120, 170, 153, 269, 693, 96, 450, 181, 39, 253, 49, 349, 174, 554, 248, 108, 315}, {}, None}, "ElementType" -> "Integer64"|>], 
TabularColumn[<|"Data" -> {{125, 173, 73, 189, 
Round[
Missing[]], 616, 140, 371, 179, 56, 146, 110, 245, 101, 413, 310, 159, 
Round[
Missing[]]}, {}, None}, "ElementType" -> "InertExpression", "CachedOriginalExpression" -> {125, 173, 73, 189, 
Round[
Missing[]], 616, 140, 371, 179, 56, 146, 110, 245, 101, 413, 310, 159, 
Round[
Missing[]]}|>]}}]|>|>];

To clean it, we can just apply replacement function to all its columns:

In[5]:=
tabClean = ResourceFunction["TransformTabular"][
  tabData, # /. Round[Missing[]] :> 0 &]
Out[5]=

We can also specify a group of columns (as a Span or List) on which to apply a numeric operation (in the present case, we should exclude the Municipality column because it is made of strings):

In[6]:=
ResourceFunction["TransformTabular"][tabClean, N[Sqrt@#] &, 2 ;;]
Out[6]=

Now on the cleaned table we can also perform an operation with ColumnwiseValue:

In[7]:=
ResourceFunction["TransformTabular"][tabClean, N[# - ColumnwiseValue@Median[#]] &, 2 ;;]
Out[7]=

Or with ColumnwiseThread:

In[8]:=
ResourceFunction["TransformTabular"][tabClean, ColumnwiseThread[Accumulate@#] &, 2 ;;]
Out[8]=

The columns specification can also be given as a list of column names of column indexes:

In[9]:=
tabInt = With[{cols = Alphabet[][[;; 10]]},
  Tabular[
   Table[AssociationThread[cols, Table[RandomInteger[100], Length@cols]], 4]]]
Out[9]=
In[10]:=
ResourceFunction["TransformTabular"][
 	ResourceFunction["TransformTabular"][
  		tabInt, If[EvenQ[#], Style[#, Red], #] &, {"a", "c", "e", "g", "i"}],
 			If[OddQ[#], Style[#, Blue], #] &, {2, 4, 6, 8, 10}]
Out[10]=

Properties and Relations (6) 

TransformTabular[tab,f] is equivalent to TransformColumns with multiple function specifications. Define a Tabular:

In[11]:=
tab = With[{cols = Alphabet[][[;; 4]]},
  Tabular[
   Table[AssociationThread[cols, Table[RandomInteger[1 + 5*c], {c, Length@cols}]], 2]]]
Out[11]=

We can apply a transformation for each column with TransformColumns:

In[12]:=
TransformColumns[tab,
 {"a" -> Function[#a - ColumnwiseValue[Min[#a]]],
  "b" -> Function[#b - ColumnwiseValue[Min[#b]]],
  "c" -> Function[#c - ColumnwiseValue[Min[#c]]],
  "d" -> Function[#d - ColumnwiseValue[Min[#d]]]}]
Out[12]=

Or apply it a single time with TransformTabular[f,tab]:

In[13]:=
ResourceFunction[
 "TransformTabular"][tab, # - ColumnwiseValue[Min[#]] &]
Out[13]=

Check that the two results are equal:

In[14]:=
% == %%
Out[14]=

When the function does not involve ColumnwiseValue or ColumnwiseThread, TransformTabular[tab,f] is equivalent to Query (with Normal):

In[15]:=
ResourceFunction["TransformTabular"][tab, #^2 &]
Out[15]=
In[16]:=
Query[All, All, #^2 &][Normal@tab] // Tabular
Out[16]=

Check that the two results are equal:

In[17]:=
% == %%
Out[17]=

Publisher

Daniele Gregori

Version History

  • 1.0.0 – 14 May 2025

Related Resources

Author Notes

The development of this function benefitted from suggestions by the WFR Team.

License Information