Script para recorrer y agrupar columnas por nombre, dinámicamenteAsí que estoy tratando de resolver esto y simplemente no funciona del todo.
Tengo una tabla con un par clave-valor que he DIVIDIDO de alto a ancho. Termino con alrededor de 10k columnas que tienen una estructura de nombres regular, como
"15.02.0 param1", "15.02 param2", "15.02 param3"...."15.03 param1", "15.03 param2", "15.03 param3",...
¿Cómo puedo mirar a través de todas estas columnas y agruparlas dinámicamente por el término inicial? es decir. todas las columnas del 15,02 % en un grupo, todas las columnas del 15,03 %, todas las del 15,04 %,... todas las del 17,06 %... y nombrar el grupo según el número del grupo?
Mi script simplemente agrupa todo en un solo grupo. ug.
//**split Aggregate Data from TALL to WIDE, grouping WIDE columns by StepID
dt = current data table();
Summarize( dt, RecipeStepIndex = by( :RecipeStepId) );//get list of unique RecipeStepID's
//split the table TALL to WIDE
dt << Split(
Split By( :RecipeStepId, :ParameterName, :AggregateFunction ),
Split( :Value ),
Group( :Recipe, :ProcessTime, :Tool, :Chamber, :Lot, :WaferScribe ),
Output Table( "AggWide" ),
Remaining Columns( Drop All ),
Sort by Column Property,
dt << sort( by( :Recipe, :Tool, :Chamber, :Lot, :WaferScribe ))<BR />
);
dtAggWide = current data table();
ColNamesList = dtAggWide << get column names(string, continuous); //get the column names of the WIDE table
//Create an empty list for the matching columns
RecipeStepList = {};
// Find matching column names
For( i = 1, i <= N items( RecipeStepIndex ), i++,
For( j = 1, j <= N Items( ColNamesList ), j++,
If(
Contains( ColNamesList[j], RecipeStepIndex[i] ),
Insert Into( RecipeStepList, ColNamesList[j] ),
);
);
);
// If groups of columns are found, create Col groupings
If( N Items( RecipeStepList ) > 0,
dtAggWide << select columns( RecipeStepList );
dtAggWide << group columns();
);Fusión y limpieza de datosRe: Script para recorrer y agrupar columnas por nombre, dinámicamentetengo ¡Descubrí cómo hacer que ambas versiones funcionen! Muchas gracias y felicitaciones.
Para cualquier persona en el futuro, aquí están mis versiones terminadas:
V1=
//**split Aggregate Data from TALL to WIDE, grouping WIDE columns by StepID
dt = current data table();
//Build and prefill an Array of names of the RecipeStepId
Summarize( dt, RecipeStepIndex = by( :RecipeStepId) );//get list of unique RecipeStepID's
aa_groups = Associative Array(RecipeStepIndex, Repeat({{}}, N Items(RecipeStepIndex)));
//split the table TALL to WIDE
dt << Split(
Split By( :RecipeStepId, :ParameterName, :AggregateFunction ),
Split( :Value ),
Group( :Recipe, :ProcessTime, :Tool, :Chamber, :Lot, :WaferScribe ),
Output Table( "AggWide" ),
Remaining Columns( Drop All ),
Sort by Column Property,
dt << sort( by( :Recipe, :Tool, :Chamber, :Lot, :WaferScribe ))
);
//Group the Cols by name of RecipeStepId
col_list = dtAggWIDE << Get Column Names("String"); //get the col list
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
If(!Contains(aa_groups, col_group),
aa_groups[col_group] = Eval List({col_name});
,
Insert Into(aa_groups[col_group], col_name);
);
);
For Each({{key, value}}, aa_groups, //perform the grouping
dtAggWide << Group Columns(key, value);
);
V2=
//**split Aggregate Data from TALL to WIDE, grouping WIDE columns by StepID
dt = current data table();
//Build and prefill an Array of names of the RecipeStepId
Summarize( dt, RecipeStepIndex = by( :RecipeStepId) );//get list of unique RecipeStepID's
aa_groups = Associative Array();
//split the table TALL to WIDE
dt << Split(
Split By( :RecipeStepId, :ParameterName, :AggregateFunction ),
Split( :Value ),
Group( :Recipe, :ProcessTime, :Tool, :Chamber, :Lot, :WaferScribe ),
Output Table( "AggWide" ),
Remaining Columns( Drop All ),
Sort by Column Property,
dt << sort( by( :Recipe, :Tool, :Chamber, :Lot, :WaferScribe ))
);
//Group the Cols by name of RecipeStepId
col_list = dtAggWide << Get Column Names("String");
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
If(!Contains(aa_groups, col_group),
aa_groups[col_group] = {};
);
Insert Into(aa_groups[col_group], col_name)
);
For Each({{key, value}}, aa_groups, //perform the grouping
dtAggWide << Group Columns(key, value);
);Re: Script para recorrer y agrupar columnas por nombre, dinámicamenteCreo que ese error significa que no tienes una clave en una matriz asociativa. Si probó el segundo código, su código tiene esta línea:
aa_groups = Associative Array(RecipeStepIndex, Repeat({{}}, N Items(RecipeStepIndex)));
se utiliza para inicializar aa_groups. También si el ÍndicePasoReceta no coincide con grupo_col = Palabra(1, nombre_col, " "); obtendrá ese error. Es posible que deba agregar un manejo adicional para casos como ese (agregar grupo que recopilará todas las columnas que faltan o solo agregar columnas que se encuentran).
Esto debería omitir las columnas que no tienen un grupo coincidente.
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
If(!Contains(aa_groups, col_group),
aa_groups[col_group] = Eval List({col_name});
,
Insert Into(aa_groups[col_group], col_name);
);
);
Re: Script para recorrer y agrupar columnas por nombre, dinámicamenteOK, creo que entiendo lo que quieres decir, estaba confundido por qué estabas creando un nuevo dt, pero parece solo para el ejemplo.
su segundo conjunto de código no parece funcionar para mí, pero el primer conjunto sí. ¿Alguna idea de lo que significa este error?

//Group the Cols by name of RecipeStepId
col_list = dtAggWIDE << Get Column Names("String");
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
If(!Contains(aa_groups, col_group),
aa_groups[col_group] = {};
);
Insert Into(aa_groups[col_group], col_name)
);
Show(aa_groups);
For Each({{key, value}}, aa_groups,
dtAggWide << Group Columns(key, value);
);
Re: Script para recorrer y agrupar columnas por nombre, dinámicamentedtAggWide está ahí porque es la tabla de datos que tiene las columnas que desea agrupar. En el código anterior, le falta una referencia, la forma más fácil y mejor de agregarlo sería (esto evitará usar la Tabla de datos actuales () que podría funcionar o no):
dtAggWide = dt << Split(
Split By( :RecipeStepId, :RecipeStepName, :ParameterName, :AggregateFunction ),
Split( :Value ),
Group( :Recipe, :ProcessTime, :Tool, :Chamber, :Lot, :WaferScribe ),
Output Table( "AggWide" ),
Remaining Columns( Drop All ),
Sort by Column Property,
dt << sort( by( :Recipe, :Tool, :Chamber, :Lot, :WaferScribe ))
);
Y col_list está ahí para recorrer las columnas en dtAggWide y luego agregar las columnas a las listas correctas en la matriz asociativa aa_groups
Re: Script para recorrer y agrupar columnas por nombre, dinámicamenteMmm. Estoy un poco atascado y no estoy seguro de lo que estás haciendo aquí.
¿Por qué todavía tiene dtAggWide y col_list?
//*****************************************************************
//**split Aggregate Data from TALL to WIDE, grouping WIDE columns by StepID
dt = current data table();
//Build and prefill an Array of names of the RecipeStepId
aa_groups = Associative Array();
Summarize( dt, RecipeStepIndex = by( :RecipeStepId) );//get list of unique RecipeStepID's
aa_groups = Associative Array(RecipeStepIndex, Repeat({{}}, N Items(RecipeStepIndex)));
//split the table TALL to WIDE
dt << Split(
Split By( :RecipeStepId, :RecipeStepName, :ParameterName, :AggregateFunction ),
Split( :Value ),
Group( :Recipe, :ProcessTime, :Tool, :Chamber, :Lot, :WaferScribe ),
Output Table( "AggWide" ),
Remaining Columns( Drop All ),
Sort by Column Property,
dt << sort( by( :Recipe, :Tool, :Chamber, :Lot, :WaferScribe ))
);
//Group the Cols by name of RecipeStepId
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
Insert Into(aa_groups[col_group], col_name)
);
For Each({{key, value}}, aa_groups,
dtAggWide << Group Columns(key, value);
);Re: Script para recorrer y agrupar columnas por nombre, dinámicamentePodría "rellenar previamente" la matriz asociativa, por ejemplo, con los nombres de columna basados en RecipeStepIndex. Lo más probable es que se encuentre RecipeStepIndex desde el comienzo de los nombres de las columnas divididas, por lo que aún debería funcionar.
Names Default To Here(1);
// this solution requires JMP16
dtAggWide = New Table("Untitled",
Add Rows(0),
New Column("15.02.0 param1", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.02.0 param2", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.02.0 param3", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.03 param1", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.03 param2", Numeric, "Continuous", Format("Best", 12), Set Values([]))
);
col_list = dtAggWide << Get Column Names("String");
// first get the column group names and columns// in this solution case we use associative array
aa_groups = Associative Array();
//Summarize(dt, RecipeStepIndex = by(:RecipeStepId));//get list of unique RecipeStepID's
RecipeStepIndex = {"15.02.0", "15.03"};
aa_groups = Associative Array(RecipeStepIndex, Repeat({{}}, N Items(RecipeStepIndex)));
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
Insert Into(aa_groups[col_group], col_name)
);
For Each({{key, value}}, aa_groups,
dtAggWide << Group Columns(key, value);
);
Re: Script para recorrer y agrupar columnas por nombre, dinámicamentegracias, intentare esto en breve.
Pero, ¿qué pasa con la construcción dinámica de la lista de matrices de agrupación? Básicamente, cada valor único de :RecipeStepId debe ser un nombre de grupo. Intenté hacer eso al principio, antes de dividir la tabla, guardándola en "RecipeStepIndex"
Summarize( dt, RecipeStepIndex = by( :RecipeStepId) );//get list of unique RecipeStepID's
Re: Script para recorrer y agrupar columnas por nombre, dinámicamenteHay muchas maneras de hacer esto.
Aquí hay un ejemplo que primero construye los grupos en una matriz asociativa con la clave como nombre del grupo y el valor es una lista de columnas en el grupo, luego recorre esa matriz asociativa para agrupar columnas en la tabla de datos. Para obtener los nombres de los grupos, usamos la función Word() en los nombres de las columnas. Esto requiere JMP16 debido al uso de For Each
Names Default To Here(1);
// this solution requires JMP16
dtAggWide = New Table("Untitled",
Add Rows(0),
New Column("15.02.0 param1", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.02.0 param2", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.02.0 param3", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.03 param1", Numeric, "Continuous", Format("Best", 12), Set Values([])),
New Column("15.03 param2", Numeric, "Continuous", Format("Best", 12), Set Values([]))
);
col_list = dtAggWide << Get Column Names("String");
// first get the column group names and columns<BR />// in this solution case we use associative array
aa_groups = Associative Array();
For Each({col_name}, col_list,
col_group = Word(1, col_name, " ");
If(!Contains(aa_groups, col_group),
aa_groups[col_group] = {};
);
Insert Into(aa_groups[col_group], col_name)
);
Show(aa_groups);
For Each({{key, value}}, aa_groups,
dtAggWide << Group Columns(key, value);
);

Re: Script para recorrer y agrupar columnas por nombre, dinámicamente¿Alguna forma de realizar esta búsqueda de un personaje específico y luego usarlo como nombre del grupo? ¿De esa manera es una duración dinámica para la primera sección?
Re: Script para recorrer y agrupar columnas por nombre, dinámicamenteModificaría la parte donde se determina col_group y luego continuaría en consecuencia.