Estoy intentando extraer valores de columna de filas seleccionadas en una etiqueta concatenada que se utiliza para anotar una línea de referencia agregada en una distribución.
El mensaje de error en la concatenación se debe a una falta de coincidencia en las dimensiones de la lista. Las llamadas de matriz asociativa utilizadas para recopilar valores de las filas seleccionadas eliminan los valores duplicados, lo que genera listas de valores únicos.
Mi objetivo es obtener el nombre, la edad y el peso de una fila seleccionada determinada en una cadena que pueda usarse como etiqueta en una llamada de referencia adicional posterior.
Con el enfoque actual tengo códigos de error y en algunos casos una desalineación en los datos sin un código de error.
Ejemplo 1: condición de error: se encuentran tres ponderaciones únicas en las que las listas de edades y nombres solo encontraron dos elementos cada una de las filas seleccionadas. La tercera iteración de la indexación falla debido a las diferencias en las dimensiones de la lista.
Ejemplo 2: datos desalineados: hay tres filas seleccionadas con los nombres Leslie y Patty. Hay dos entradas con el nombre Patty, una de 14 años y peso 85, la otra de 16 años y peso 134. Una de las entradas de Patty y la de Leslie tienen 14 años. El resultado de los datos desalineados se puede ver si la etiqueta solo considera las listas de nombre {"LESLIE", "PATTY"} y edad {14,16}. La indexación solo generaría dos entradas, la primera es "Leslie ...14" y la segunda es "Patty ...16", que es una asociación correcta, pero "Patty ...14" no se incluye y las dimensiones de la lista dependen de los datos.
¿Debo eliminar las llamadas de matriz asociativa y, en su lugar, pasar a un enfoque de subconjunto/tabla o debo revisar las llamadas de matriz asociativa para tener elementos de lista que sean listas con el nombre, la edad y el peso capturados en cada iteración o para cada fila seleccionada?
Gracias,
Bryan
Código de error cuando se exceden las dimensiones de las listas:
el argumento debe ser un carácter en la fila 41 en el acceso o evaluación de 'Concat', argumento incorrecto (theAges[i]), theNames[i] || /*###*/" ..." || /*###*/theAges[i] /*###*/

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
col_name_list = dt << get column names( string );
newColName = "State";
// New column: State
If( !Contains( col_name_list, newColName ),
Local( {dt, tempStrings},
dt = Data Table( "Big Class" );
dt << New Column( "State", Character, "Nominal" ) << Begin Data Update;
tempStrings = {"CA", "WA", "OR"};
For Each Row( dt, :State = tempStrings[Sequence( 1, 3, 1, 1 )] );
dt << End Data Update;
);
//Make it a double Patty :), another person with the same name.
dt << Add Rows( 1, At End );
//Cheat and use a constant of 41 for the last row index
dt[[41], {name, age, sex, height, weight, State}] = {{"PATTY", 16, "F", 57, 134, "WA"}};
);
// For illustration, select some names
dt << select where( Contains Item( :name, {"LESLIE", "PATTY"} ) );
dist = dt << Distribution(
Stack( 1 ),
Continuous Distribution(
Column( :height ),
Quantiles( 0 ),
Summary Statistics( 0 ),
Horizontal Layout( 1 ),
Normal Quantile Plot( 0 ), // disable, if the user enabled it in the preferences :)
Vertical( 0 ),
Set Bin Width( 2 ),
Process Capability( 0 )
//);
),
By( :State )
);
// get all reports
// if there is a BY group, get the info - if there is none, put it into a list
If( Is List( dist ),
dists=dist;
myBys = Transform each ({myexpr} , dist << Get Where Expr, Arg(myExpr , 2 ))
, //no By
dists = Eval List( {dist} );
myBys= {};
);
//get the reports
distRPTs = Transform Each( {dist}, dists, Report( dist ) );
// Find the Midpoints of the bins the selected rows are in
dist << Save( "Level Midpoints" );
//loop though the By groups and add the reflines
For Each( {report, idx}, distRPTs,
//report = distRPTs[2]; idx=2;
selected rows = dt << get selected rows;
// there is a BY group -> restrict the selection
if(N Items(myBys),
Eval( Eval Expr( selected rows = dt << get rows where( Contains( Expr( selected rows ), Row() ) & :State == Expr( myBys[idx] ) ) ) );
);
theBins = (Associative Array( Column( dt, N Cols( dt ) )[selected rows] )) << get keys;
theNames = (Associative Array( Column(dt, "name") [dt << get selected rows] )) << get keys;
theAges = (Associative Array( Column(dt, "age") [dt << get selected rows] )) << get keys;
theWeights = (Associative Array( Column(dt, "weight") [dt << get selected rows] )) << get keys;
For( i = 1, i <= N Items(theWeights), i++,
theLabels[i] = theNames[i] || " ..." || theAges[i] ;
);
);
dt << delete columns( N Cols( dt ) );Hola Bryan, puedes usar una columna de transformación para preparar los resultados correctos y luego seleccionar las entradas que necesitas:

Ver más...Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
col_name_list = dt << get column names( string );
newColName = "State";
// New column: State
If( !Contains( col_name_list, newColName ),
Local( {dt, tempStrings},
dt = Data Table( "Big Class" );
dt << New Column( "State", Character, "Nominal" ) << Begin Data Update;
tempStrings = {"CA", "WA", "OR"};
For Each Row( dt, :State = tempStrings[Sequence( 1, 3, 1, 1 )] );
dt << End Data Update;
);
//Make it a double Patty :), another person with the same name.
dt << Add Rows( 1, At End );
//Cheat and use a constant of 41 for the last row index
dt[[41], {name, age, sex, height, weight, State}] = {{"PATTY", 16, "F", 57, 134, "WA"}};
);
// For illustration, select some names
dt << select where( Contains Item( :name, {"LESLIE", "PATTY"} ) );
dist = dt << Distribution(
Stack( 1 ),
Continuous Distribution(
Column( :height ),
Quantiles( 0 ),
Summary Statistics( 0 ),
Horizontal Layout( 1 ),
Normal Quantile Plot( 0 ), // disable, if the user enabled it in the preferences :)
Vertical( 0 ),
Set Bin Width( 2 ),
Process Capability( 0 )
//);
),
By( :State )
);
// get all reports
// if there is a BY group, get the info - if there is none, put it into a list
If( Is List( dist ),
dists=dist;
myBys = Transform each ({myexpr} , dist << Get Where Expr, Arg(myExpr , 2 ))
, //no By
dists = Eval List( {dist} );
myBys= {};
);
//get the reports
distRPTs = Transform Each( {dist}, dists, Report( dist ) );
// Find the Midpoints of the bins the selected rows are in
dist << Save( "Level Midpoints" );
dt << transform column ("label",Character, Formula (:name || " ..." || Char(age)));
//loop though the By groups and add the reflines
For Each( {report, idx}, distRPTs,
//report = distRPTs[2]; idx=2;
selected rows = dt << get selected rows;
// there is a BY group -> restrict the selection
if(N Items(myBys),
Eval( Eval Expr( selected rows = dt << get rows where( Contains( Expr( selected rows ), Row() ) & :State == Expr( myBys[idx] ) ) ) );
);
myLabels = Associative Array(:label[selected rows]) << get keys;
print(myLabels)
);
dt << delete columns( N Cols( dt ) );
Hola @hogi
He combinado tus ideas en esta publicación y la publicación relacionada sobre cómo agregar una línea de referencia.
La solución que funciona para alinear la información correcta sin pérdida de valores repetidos mientras se agregan contenedores correctamente a los gráficos en la pila fue preparar listas a partir de los campos en la tabla indexando las filas seleccionadas dentro de un bucle for anidado.
- Distribuciones de parcelas
- Recopilar por criterios en una matriz para cada uno de los gráficos en una instancia del informe (3 gráficos para cada elemento de datos, 3 matrices)
- Recopilar los informes en un objeto utilizado en la iteración
- Agregue los puntos medios de los datos graficados (3 gráficos, 3 columnas adjuntas a la tabla de datos)
- Recorrer el objeto con un For Each para acceder y ampliar cada gráfico
- Inicializar variables de lista para contenedores y etiquetas
- Seleccionar las filas de datos en función de criterios de referencia (por ejemplo, número de serie)
- Refinar filas seleccionadas según criterios que coincidan con los criterios Por en los gráficos
- Utilice un bucle for para tantas filas seleccionadas como sea posible
- Recopile los contenedores de las columnas de puntos medios adjuntas (cada gráfico tiene una columna respectiva)
- Recopile la información en la etiqueta de las columnas interesantes (por ejemplo, fecha de medición, número de serie)
- Agregar línea de referencia con la información recopilada.
- Elimine las columnas de punto medio para evitar datos obsoletos en caso de que cambie la configuración del gráfico en el paso 1.
Cambios clave que ayudaron:
1. Cambiar de matriz asociativa a listas pobladas mediante iteración para evitar la eliminación de valores duplicados y mantener la alineación.
2. Cree variables separadas para cada una de las condiciones.
Espero que esto ayude a cerrar el círculo. Agradezco tus consejos, ya que me permitieron aprender y progresar.