Asignar valores que contengan la listaHola,
Este problema realmente me desconcierta.
Quiero asignar valores de la tabla 1 (dt_group) a la tabla 2 (dt_subset).
Por lo tanto, itere a través de cada fila de la Tabla 2 y luego compare las filas de la columna Producto de la Tabla 2 con cada fila de los Grupos de productos de la Tabla 1 y luego asigne los valores de Límites a la columna _LIMITS en la Tabla 1 si se encuentra una cadena coincidente. ¿Cómo puedo programar esto?
Tabla 1:

Tabla 2:

Ya lo intenté y tengo problemas al comparar cadenas de ambas tablas...
Names Default To Here( 1 );
dt_subset = Current Data Table();
col_names = dt_subset << get column names( string );
dt_group = Data Table( "dt_groups" );
aa_limits = Associative Array( dt_group:Tests << get values, dt_group:Limits << get values );
For( i = 1, i <= N Items( aa_limits ), i++,
If( Contains( aa_limits, col_names[i] ),
curname = Column( dt_subset, col_names[i] ) << get name;
new_col = dt_subset << New Column( (curname || "_LIMITS"),
Numeric,
Continuous,
Format( "Percent", 12, 2 )
);
dt_subset << Move Selected Columns( new_col, After( Column( dt_subset, curname ) ) );
)
);
Gracias,
J
Automatización y scriptingRe: Asignar valores que contienen en la lista¡Gracias Jim y Jarmo!
Aquí hay otro método que utilicé para resolverlo.
Names Default To Here( 1 );
dt_subset = Data Table( "subset table.jmp" );
dt_group = Data Table( "dt_groups.jmp" );
list1 = dt_group:Limits << get values;
list2 = dt_group:ProductGroups << get values;
list3 = dt_group:Tests << get values;
col_names = dt_subset << get column names( string );
aa_limits = Associative Array( dt_group:Tests << get values, dt_group:Limits << get values );
For Each( {val1, idx1}, list2,
For Each Row(
dt_subset,
For Each( {val3, idx2}, list3,
If( Contains( val1, dt_subset:Product ),
As Column( dt_subset, list3[idx1] || "_LIMITS" ) = list1[idx1]
)
)
);
);
Re: Asignar valores que contienen en la listaEste es mi intento. Utiliza las tablas proporcionadas, por lo que no crea ninguna columna nueva y solo establece fórmulas temporales para calcular los valores (lo más probable es que se pueda simplificar bastante si la tabla del subconjunto no tiene columnas creadas previamente).
Names Default To Here(1);
dt_subset = Open("$DOWNLOADS/subset table.jmp");
dt_group = Open("$DOWNLOADS/dt_groups.jmp");
aa_tests = Associative Array();
For Each Row(dt_group,
limitname = :Tests || "_LIMITS";
aa_tests[limitname] = Associative Array();
aa_tests[limitname]["Groups"] = Words(:ProductGroups, " ,");
aa_tests[limitname]["Limit"] = :Limits
);
colnames = dt_subset << Get Column Names("Continuous", "String");
For Each({{testname, specs}}, aa_tests,
If(!Contains(colnames, testname),
Write("\!NNo Match: " || testname);
Continue();
);
Column(dt_subset, testname) << Formula(
If(Contains(specs["Groups"], :Product),
specs["Limit"];
,
.
);
);
dt_subset << run formulas;
Column(dt_subset, testname) << Delete Formula;
);
Re: Asignar valores que contienen en la listaAquí hay un enfoque completamente diferente. Utiliza las capacidades de unión de JMP en lugar de intentar hacer todo con bucles y comparaciones. Creo que funciona como quieres, pero verifica los resultados.
</CODE></PRE>
<PRE><CODE class=" language-jsl">Names Default To Here( 1 );
dt_subset = Data Table( "subset table" );
col_names = dt_subset << get column names( string,continuous );
dt_group = Data Table( "dt_groups" );
// Expand dt_group:ProductGroups into separate columns
dt_group << text to columns( delimiter( "," ), columns( :ProductGroups ) );
// Stack the resulting columns
dt_group_col_names = dt_group << get column names( string );
// Remove the first 3 columns from the list
Remove From( dt_group_col_names, 1, 3 );
// Stack data table
// → Data Table( "Stacked dt_groups" )
dt_stack_group = dt_group << Stack(
columns( dt_group_col_names ),
Source Label Column( "Label" ),
Stacked Data Column( "Product" ),
"Non-stacked columns"n( Keep( :Tests, :Limits ) ),
Output Table( "Stacked dt_groups" )
);
// Get rid of the Label column
dt_stack_group << delete columns( :Label );
// Stack the subset table
// Add a RowNum column to the table to preserve the order
dt_subset << New Column( "RowNum", set each value( Row() ) );
dt_stack_subset = dt_subset << Stack(
columns(
col_names
),
Source Label Column( "Tests" ),
Stacked Data Column( "Data" ),
Name("Non-Stacked columns")(Keep({Product, RowNum})),
Output Table( "Stack of subset table" )
);
// Join the 2 stacked tables
dt_joined = dt_stack_subset << Join(
With( dt_stack_group ),
Merge Same Name Columns,
Match Flag( 0 ),
By Matching Columns( :Product = :Product, :Tests = :Tests ),
Drop multiples( 0, 0 ),
Include Nonmatches( 1, 0 ),
Preserve main table order( 1 ),
Output Table( "Joined stack data" )
);
// Split the table back to original form
dt_final = dt_joined << Split(
Split By( :Tests ),
Split( :Data, :Limits ),
Group( :RowNum ),
Output Table( "Final" ),
Sort by Column Property
);
// Cleanup and rearrange the Final data table
dt_final << delete columns( :RowNum );
// Rename the columns
For( i = 2, i <= N Cols( dt_final ), i++,
theName = Column( dt_final, i ) << get name;
If(
Starts With( theName, "Data" ), Column( dt_final, i ) << set name( Substr( theName, 6 ) ),
Starts With( theName, "Limits" ),
Column( dt_final, i ) << set name( Substr( theName, 8 ) || "_LIMITS" )
);
);
// Reorder the columns
For( i = Length( col_names ), i >= 1, i--,
If( Try( Column( dt_final, col_names[i] || "_LIMITS" ) << get name, "" ) != "",
theName = ":\!"" || col_names[i] || "_LIMITS" || "\!"n";
Eval( Parse( "dt_final << Move Selected Columns( " || theName || ",to first);" ) );
//dt_final << Move Selected Columns( :"Test5^0.8_LIMITS"n,to last)
);
theName = ":\!"" || col_names[i] || "\!"n";
Eval( Parse( "dt_final << Move Selected Columns( " || theName || ",to first);" ) );
);
dt_final << move selected columns( :Product, to first );
close( dt_stack_group, nosave);
close( dt_stack_subset, nosave);
close( dt_joined, nosave);Re: Asignar valores que contienen en la lista¡Gracias, Jim! No es exactamente lo que estoy buscando.
Un ejemplo:
Compare la fila 1 de la columna Producto de la tabla 2 con todas las cadenas de la primera fila de ProductGroups y luego asigne el valor límite correspondiente

Re: Asignar valores que contienen en la listaAsí es como haría lo que has especificado.
Names Default To Here( 1 );
dt_subset = Current Data Table();
col_names = dt_subset << get column names( string );
dt_group = Data Table( "dt_groups" );
//aa_limits = Associative Array( dt_group:Tests << get values, dt_group:Limits << get values );
For( i = 1, i <= N Rows( dt_group ), i++,
found = Contains( col_names, dt_group:Tests[i] );
If( found > 0,
//curname = Column( dt_subset, col_names[i] ) << get name;
Eval(
Eval Expr(
new_col = dt_subset << New Column( col_names[found] || "_LIMITS",
Numeric,
Continuous,
Format( "Percent", 12, 2 ),
set each value( Expr( dt_group:limits[i] ) )
)
)
);
dt_subset << Move Selected Columns( new_col, After( Column( dt_subset, col_names[found] ) ) );
)
);
Asegúrese de que los nombres en la columna dt_group:tests coincidan con los nombres de las columnas. Es posible que haya algunos espacios en blanco adicionales en los nombres de las columnas en comparación con los valores de Tests.