Justo cuando pensé que entendía Eval y Expr...He estado trabajando en este problema durante dos días revisando las entradas de este grupo de discusión, consultando la guía de scripts, etc., pero todavía no puedo descubrir qué está mal.
Estoy intentando usar una variable para hacer referencia a una columna. Desde las filas 65 a 75 del script (justo antes de For Each Row), estoy probando todo tipo de formas de usar Expr y Eval y Name Expr y As Column, etc. para que esto funcione. El script actual muestra solo la iteración más reciente.
Dependiendo del valor de aggOption, quiero que la columna Agg Minute (Option 1) se complete de una de tres maneras diferentes. Si sustituye el nombre de la columna real: "Agg Minute (Option 1)"n en lugar de Eval( colName3), funciona como se espera. Sin embargo, sin importar qué combinación de Eval, Expr, etc. use para definir la variable o evaluarla, obtengo el siguiente mensaje de error...

... O el script se ejecuta sin errores pero la columna no se completa.
Entonces parece que el lado izquierdo de la asignación no se interpreta como un nombre de columna.
Estoy seguro de que debe tratarse de un simple malentendido de mi parte sobre cómo funcionan Eval y Expr o cómo funciona la función Choose, pero no logro entender de qué se trata.
¿Alguien tiene alguna idea de lo que estoy haciendo mal?
Gracias como siempre.
Names Default To Here( 1 );
// SETUP: Create Raw Data Table
Try( Close( "Interpolated Data"));
Try( Close( "Test rt"));
rt = New Table( "Test rt",
Add Rows( 5 ),
New Column( "Timestamp", Continuous, Format( "m/d/y h:m", 19 ), set values( [3742070400, 3742070880, 3742071360, 3742071840, 3742072320] ) ),
New Column( "Data", set values( [899.084, 897.387, 898.518, 897.575, 897.387] ) )
);
t1 = column( rt,1) << Get Name;
t2 = column( rt,2) << Get Name;
timeCol = Parse(":" || t1);
dataCol = Parse(":" || t2);
Print( timeCol);
Print( dataCol);
rtRows = N Rows( rt );
startTime = rt:Timestamp[1];
endTime = rt:Timestamp[rtRows];
minDuration = (endTime - startTime) / 60;
// CREATE SECONDARY TABLE
dt = New Table( "Interpolated Data Temp" );
dt << New Column( "Timestamp", Format( "m/d/y h:m", 19 ), Set Display Width( 250 ) );
dt << Add Rows( minDuration );
For Each Row( dt, :Timestamp[] = Sequence( startTime, endTime, 60 ) );
// JOIN BOTH TABLES
dt << Join(
With( rt ),
Suppress formula evaluation( 0 ),
Select( :Timestamp ),
SelectWith( Name Expr(dataCol)),
By Matching Columns( :Timestamp = :Timestamp ),
Drop multiples( 0, 0 ),
Include Nonmatches( 1, 0 ),
Preserve main table order( 1 ),
Output Table( "Interpolated Data" )
);
dt2 = Data Table( "Interpolated Data" );
Close( dt, NoSave );
Close( rt, NoSave );
// CREATE AGG MINUTE/AGG QUADRANT COLUMNs
// These are the columns that will define which minutes are included in each quadrant and how the quadrant will be labled.
// The choice of how the columns will be filled depends on the Option chosen above.
// **************************************************************************
aggOption = 1;
colName1 = "Agg Minute (Option " || char(aggOption) || ")";
colName2 = "Agg Quadrant (Option " || char(aggOption) || ")";
Print( colName1);
Print( ColName2);
colName3 = Name Expr(":" || colName1);
colName4 = Name Expr(":" || colName2);
Print( colName3);
Print( colName4);
New Column(colName1, Numeric, "Ordinal", Format("Best", 12), Set Display Width(116)); // To Do: Add chosen agg option to column name
New Column(colName2, Numeric, "Ordinal", Format("Best", 12), Set Display Width(116)); // To Do: Add chosen agg option to column name
For Each Row(dt2,
Eval(colName3) = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);Automatización y scriptingRe: Justo cuando pensé que entendía Eval y Expr...Casi nunca es necesario empezar a jugar con : (agregar : : como cadena) y menos aún con Parse(). Cuando se configuran valores para una columna con For Each Row, se puede hacer algo como esto, por ejemplo
For Each Row(
dt2,
Column(dt2, colName1)[Row()] = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);
Esta no es la única opción, pero es muy sencilla. Si realmente quieres empezar a jugar con expresiones, esta es una forma de hacerlo.
Eval(EvalExpr(
For Each Row(
dt2,
Expr(Name Expr(AsColumn(dt2, colName1))) = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);
));
Una cosa buena con EvalExpr (lo mismo ocurre con Substitute) es que puedes ver fácilmente la expresión que se evaluará si se usa Eval, pero seleccionando la parte EvalExpr() y luego ejecutándola

Re: Justo cuando pensé que entendía Eval y Expr...Gracias, Jarmo.
Probé opciones con análisis y con y sin los dos puntos iniciales, pero sin éxito. Sin embargo, no probé las combinaciones que mostraste anteriormente. Tiene todo el sentido una vez que lo ves hecho.
Re: Justo cuando pensé que entendía Eval y Expr...Es interesante que necesites la función Row() aquí cuando no es necesaria si se usa el nombre real de la columna. No lo habría adivinado.
Re: Justo cuando pensé que entendía Eval y Expr...Ese es mi método preferido, ya que uso Column(dt, colname) siempre que puedo (también puedes omitir Row() y usar Column()[]). Creo que también debería funcionar con As Column()
For Each Row(
dt2,
As Column(dt2, colName1) = Choose(aggOption, // Substituting an actual column name (:"Agg Minute (Option 1)"n works)
If(
Minute(:Timestamp) < 15, 15, // Option 1
Minute(:Timestamp) < 30, 30,
Minute(:Timestamp) < 45, 45,
0
),
If(
Minute(:Timestamp) < 15, 0, // Option 2
Minute(:Timestamp) < 30, 15,
Minute(:Timestamp) < 45, 30,
45
),
If(
0 < Minute(:Timestamp) <= 15, 15, // Option 3
15 < Minute(:Timestamp) <= 30, 30,
30 < Minute(:Timestamp) <= 45, 45,
0
)
)
);
pero en mi opinión, As Column() es mucho más molesto de usar, así que no lo uso mucho... Excepto cuando lo uso con Name Expr() y estoy tratando de crear algo que requiere que tengas el formato :col o simplemente es más limpio tener la columna en ese formato (como en fórmulas).