Subscribe Bookmark RSS Feed

Transposing a table with custom arguments

david_t_pitchfo

Community Trekker

Joined:

Feb 10, 2014

I am trying to transpose a table with a known Label column name, but Transpose column names that are only known at runtime. I have been trying for hours to figure out how to do this, but the task is greatly complicated by JSL mistaking the Transpose command for the matrix Transpose function and he Columns() argument to it for the function that gets the names of all columns in the table. In the following code, the list columns is populated with the names of the columns I want to transpose.

//Create the transpose expression

transposeExpr = Expr(Transpose(Columns(), Label(:Wt or Rd)));

//Pull the Columns argument expression out of it (this keeps me from having to create it myself and have it mistaken for the Columns() function)

columnsExpr = Arg(transposeExpr, 1);

For(i = 1, i <= numColumns, i++,

    Insert Into(columnsExpr, Name Expr(As Column(colNames)));

);

Remove From(transposeExpr, 1);

Insert Into(transposeExpr, Name Expr(columnsExpr), 1);

cdt = Current Data Table();

cdt << Transpose(Name Expr(columnsExpr), Label(:Wt or Rd));

However, this still doesn't appear to work because columnsExpr still evaluates to a list of names of all the columns in the current table, rather than the Columns argument with actual references to the table. (I think it interprets these references are arguments to Columns the function)

Can anyone please explain what I am doing wrong?

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

Not sure if I understand exactly what you want to do, but maybe this example would be helpful, assuming the fitness data is current.

collist = {:Age, :Oxy, :Runtime};

Data Table( "Fitness" ) << Transpose(

    columns( eval(collist)),

    Label( :Name ),

    Output Table( "Transpose of Fitness" )

)

4 REPLIES
pmroz

Super User

Joined:

Jun 23, 2011

When I have trouble like this I resort to building a string dynamically, and executing it with eval(parse()).  It's somewhat brute force, but I get tied up in knots with all of the various functions like expr, eval, parse, name expr, etc.

This should do it:

transposeStr = "cdt << Transpose(Columns(";

For(i = 1, i <= numColumns, i++,

    transposeStr = transposeStr || ":" || colNames[i] || ", ";

);

// Remove the last comma

clen = length(transposeStr);

transposeStr = substr(transposeStr, 1, (clen - 2));

// Add the label argument

transposeStr = transposeStr || "), Label(:Wt or Rd))";

eval(parse(transposeStr));

Solution

Not sure if I understand exactly what you want to do, but maybe this example would be helpful, assuming the fitness data is current.

collist = {:Age, :Oxy, :Runtime};

Data Table( "Fitness" ) << Transpose(

    columns( eval(collist)),

    Label( :Name ),

    Output Table( "Transpose of Fitness" )

)

david_t_pitchfo

Community Trekker

Joined:

Feb 10, 2014

This appears to work. I do this:

colList = List();

For(i = 1, i <= numColumns, i++,

    Insert Into(colList, Column(colNames));

);

cdt = Current Data Table();

cdt << Transpose(Columns(Eval(colList)), Label(:Wt or Rd));

Why do I have to cal Eval on colList in the final message? What is the difference between Column() and As Column()?

mpb

Super User

Joined:

Jun 23, 2011

1. Transpose( Columns() .... ) expects a bunch of column names separated by commas, as you would fill in manually. It does not expect the name of a list and doesn't know how to extract the info from the name of the list containing the column names of interest. The eval function bridges the gap. This is how I view the issue but someone else may have a more technically precise way of explaining it.

2. Column() versus As Column: I'm not sure how they differ. The short examples in the docs make them seem interchangeable in function. I'd be interested someone can point to differences between them.