Cómo recorrer filas de grupos creados por 2 columnasHola a todos,
Tengo una pregunta bastante simple pero no puedo encontrar la respuesta exacta en el foro. Aquí está mi tabla de datos de muestra:

Básicamente, tiene 4 columnas, y necesito recorrer cada uno de los elementos combinados que se generan a partir del "grupo 1" y el "grupo 2", pero si y solo cuando el número de "elemento" es diferente, abra la ruta de todos los archivos en la columna "ruta". . Por ejemplo, en las primeras 2 filas, tenemos la combinación "aA", y debido a que los elementos también son diferentes, el script debe abrir las rutas de archivo 1 y 2.
Fusión y limpieza de datosRe: Cómo recorrer filas de grupos creados por 2 columnasSí, eso fue realmente muy útil. La variable file_list era confusa, ya que no es estrictamente necesaria para abrir los archivos (pero, supongo, que es útil más adelante al cerrar todos los archivos nuevamente (?), por ejemplo, o alguna otra manipulación). Tengo que admitir que también me tomó un tiempo comprender la variable "file_path", que se asigna a una ruta de archivo diferente en cada iteración, y que no importa cómo se llame. (En mi cabeza, lo interpreto ahora como un vehículo que selecciona una ruta de archivo tras otra de la lista filepaths_to_open y permite que el usuario haga "algo" con ella).
¡Gracias! Cada semana, un pequeño crecimiento de conocimiento es mejor que nada en absoluto.
PD: Lo siguiente que solo pude escribir basado en mi comprensión de sus explicaciones. De nuevo, muy útil.
Names Default To Here( 1 );
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
For Each( {file_path}, filepaths_to_open, Open( file_path ) );
Re: Cómo recorrer filas de grupos creados por 2 columnasCreo que son más fáciles de entender escribiendo un script de demostración (modifiqué For Each un poco para agregar idx, podría hacer que sea un poco más fácil entender cómo funciona)
Names Default To Here(1);
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
show(filepaths_to_open);
file_list = {};
show(file_list);
For Each({file_path, idx}, filepaths_to_open,
show(idx, file_path);
Insert Into(file_list, Open(file_path));
show(file_list);
);
- Uso file_list para recopilar las referencias a las tablas de datos que se abren (no necesito las rutas de archivo porque ya las tengo en filepaths_to_open, pero no tengo referencias)
- Open(file_path) devolverá una referencia al archivo abierto e Insertar en luego agregará esa referencia a file_list.
- {filepath} proviene de cómo Para cada función debería ser usado. Básicamente, recorrerá filepaths_to_open y devolverá cada elemento (uno por uno) en la variable file_path.
filepaths_to_open = {"$SAMPLE_DATA/Big Class.jmp", "$SAMPLE_DATA/Probe.jmp", "$SAMPLE_DATA/Iris.jmp"};
file_list = {};
idx = 1;
file_path = "$SAMPLE_DATA/Big Class.jmp";
file_list = {DataTable("Big Class")};
idx = 2;
file_path = "$SAMPLE_DATA/Probe.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe")};
idx = 3;
file_path = "$SAMPLE_DATA/Iris.jmp";
file_list = {DataTable("Big Class"), DataTable("Probe"), DataTable("Iris")};
Ojalá responda algunas de las preguntas.
Re: Cómo recorrer filas de grupos creados por 2 columnas@jthi , solo quiero hacer algunas preguntas con respecto a la última parte del código, es decir, no lo entiendo.
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);
file_list = {};
Esta es una lista vacía. El ciclo llenará esto a través de Insertar en (file_list, Open (file_path)). ¿Por qué no se puede simplemente usar la lista ya contenida en filepaths_to_open? Además, no entiendo cómo Open(file_path) insertará algo en la lista. ¿No es esto solo una función para abrir un archivo? ¿Cómo puede contribuir todo ello a una lista?
{file_path}Esto, yo tampoco lo entiendo. ¿Es esto solo un marcador de posición para las rutas de archivo reales?
¿Quizás tienes una referencia que explique estas cosas? Desde ya muchas gracias de antemano.
Re: Cómo recorrer filas de grupos creados por 2 columnasTendrá que modificar los cálculos de ValidFile y posiblemente la selección de filas según cómo cree la comprobación de ValidFile.
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
If(Col Sum(1, :g1, :g2, :i) == 1 & Col Number(:i, :g1, :g2) > 1,
1
,
0
);
));Re: Cómo recorrer filas de grupos creados por 2 columnas@jthi , ordenado, como siempre. Buen aprendizaje, gracias.
Re: Cómo recorrer filas de grupos creados por 2 columnasMe las arreglé para encontrar uno creando otra columna, "Única":
new_col = dt << New Column("Unique", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2);
));
rows_to_open = dt << Get Rows Where(:ValidFile == 1 & :Unique != 1);
Re: Cómo recorrer filas de grupos creados por 2 columnas¡Gracias jti! Una última pregunta, ¿cómo se supone que debo modificar aún más la fórmula para ignorar si esas columnas g1, g2 y solo tengo 1 combinación de archivo válido?

Re: Cómo recorrer filas de grupos creados por 2 columnasEdité mi mensaje para cambiar el nombre de la variable anterior. No estamos sumando columnas de caracteres, las estamos usando de la agrupación (). Y usamos 1 para que tengamos algo que aumentará en 1 por cada fila del grupo. Podría ser una buena idea crear diferentes tipos de fórmulas usando esas funciones para que sea más fácil entender cómo funcionan, el índice de secuencias de comandos también proporciona algunos ejemplos.
Col Suma(nombre,)
Re: Cómo recorrer filas de grupos creados por 2 columnasHola Jthi,
Gracias por una gran respuesta con 3 opciones diferentes. Una de las notas al margen es que tengo que eliminar "1" de la variable rows_to_open1 para que el código se ejecute. Si puede corregir este error tipográfico para referencia futura, ¡sería genial!
Aparte de eso, tengo una pregunta relacionada con tu respuesta. ¿Cuál es el propósito del valor "1" en cada uno de Col Sum, Col Cumulative Sum y Col Max (Col Sum? Y no entiendo por qué podemos sumar el valor de los caracteres de las columnas g1 y g2.
Re: Cómo recorrer filas de grupos creados por 2 columnasHola Ressel,
Probé tu solución, de hecho imprimió "file path6" dos veces como mencionaste. Otro problema que vi es cuando cambié deliberadamente el valor del elemento de la fila 5 de 5 a 7 para tener 2 filas idénticas, se imprime la última fila ("ruta de archivo 6"). ¿Hay alguna manera de evitar eso? Veo una alternativa para el bucle de jthi que también tiene el mismo problema.


Re: Cómo recorrer filas de grupos creados por 2 columnas@Ressel
Creo que sería más fácil volver a pensar en la estructura de bucle, pero podría hacer que la actual también funcione de la manera que desee sin duplicar la impresión: mantenga una lista de lo que se ha impreso o descubra algún tipo de lógica adicional para evitar eso. de suceder . Creo que la siguiente idea debería funcionar:
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j < N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print(dtTemp:path[j]);
If(j + 1 == N Rows( dtTemp ),
Print(dtTemp:path[j + 1]);
)
)
);
Close( dtTemp, no save );
);
Por ejemplo, aquí no recorrería el último valor, pero verificaría si el siguiente valor sería el último, si lo sería, luego imprímalo también (si imprimió la fila actual).
Re: Cómo recorrer filas de grupos creados por 2 columnasNo estoy exactamente seguro de entender el problema correctamente, pero a continuación hay tres opciones diferentes usando, Col Sum/Col Cumulative Sum y Col Max(ColSum())
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(8),
Compress File When Saved(1),
New Column("g1", Character, "Nominal", Set Values({"a", "a", "a", "a", "a", "c", "c", "c"})),
New Column("g2", Character, "Nominal", Set Values({"A", "A", "B", "B", "B", "A", "A", "A"})),
New Column("i", Numeric, "Continuous", Format("Best", 12), Set Values([1, 3, 2, 4, 4, 5, 7, 9])),
New Column("p",
Character,
"Nominal",
Set Values({"filepath1", "filepath2", "filepath3", "filepath4", "filepath4.1", "filepath5", "filepath6", "filepath7"})
)
);
// depending how we handle duplicated g1+g2+i we would use different formulas
// if we won't open any
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Sum(1, :g1, :g2, :i);
));
/*
// if we open the first one
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Cumulative Sum(1, :g1, :g2, :i);
));
*/
/*
// if we don't open g1+g2 at all
new_col = dt << New Column("ValidFile", Numeric, Continuous, << Set Each Value(
Col Max(Col Sum(1, :g1, :g2, :i), :g1, :g2)
));
*/
rows_to_open = dt << Get Rows Where(:ValidFile == 1);
filepaths_to_open = dt[rows_to_open, "p"];
show(filepaths_to_open);
// dt << Delete Column(new_col);
// To open files loop over filepaths_to_open
stop();
file_list = {};
For Each({file_path}, filepaths_to_open,
Insert Into(file_list, Open(file_path));
);

La idea es que elegimos las filas donde ValidFile es 1 y luego abrimos esos archivos. Esta imagen demuestra los cálculos para las tres fórmulas diferentes.
Editar:
Referencia antigua fija filas_para_abrir1 a filas_para_abrir
Re: Cómo recorrer filas de grupos creados por 2 columnasInvestigue NChooseK Matrix() y vea si es adecuado para usted.En el índice de secuencias de comandos se describe como: Crea una matriz de nChooseK(n,k) filas y K columnas que forman todas las combinaciones de k enteros del 1 al n.
Me pregunto si se puede cambiar para que funcione con tipos de datos de caracteres.
Names Default To Here( 1 );
Print( NChooseK Matrix( 5, 3 ) );
__________________________
Prints:
[ 1 2 3,
1 2 4,
1 2 5,
1 3 4,
1 3 5,
1 4 5,
2 3 4,
2 3 5,
2 4 5,
3 4 5]
Re: Cómo recorrer filas de grupos creados por 2 columnasHola, lo siguiente al menos comienza lo que quieres hacer. Solo tendrás que cambiar el " Imprimir( dtTemp:ruta[j], dtTemp:ruta[j + 1] )" Parte con la función para abrir un archivo.
Desafortunadamente, sin embargo, la forma en que lo escribí, este script imprime "ruta de archivo 6" dos veces en el registro, por lo que también abrirá "ruta de archivo 6" dos veces si se modifica en consecuencia. Estoy seguro de que hay una forma de evitarlo (como verificar si ya se ha abierto una ruta de archivo), pero se está haciendo tarde aquí. De todos modos, si descubro cómo hacer el resto también, te lo haré saber. ¡Se agradecen los comentarios!
dt = New Table( "today's challenge",
Add Rows( 7 ),
New Column( "group1",
Character,
"Nominal",
Set Values( {"a", "a", "a", "a", "c", "c", "c"} )
),
New Column( "group2",
Character,
"Nominal",
Set Values( {"A", "A", "B", "B", "A", "A", "A"} ),
Set Display Width( 70 )
),
New Column( "item",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Values( [1, 3, 2, 4, 5, 7, 9] )
),
New Column( "path",
Character,
"Nominal",
Set Selected,
Set Values(
{"file path 1", "file path 2", "file path 3", "file path 4",
"file path 5", "file path 6", "file path 7"}
)
)
);
dt << New Column( "PairedGroup", formula( :group1 || :group2 ) );
PairedGroupList = Associative Array( dt:PairedGroup ) << Get Keys;
dt << Clear Column Selection;
For( i = 1, i <= N Items( PairedGroupList ), i++,
dt << Select Where( :PairedGroup == PairedGroupList[i] );
dtTemp = dt << Subset( Invisible, Selected Rows );
For( j = 1, j <= N Rows( dtTemp ), j++,
If( dtTemp:item[j] != dtTemp:item[j + 1],
Print( dtTemp:path[j], dtTemp:path[j + 1] )
)
);
Close( dtTemp, no save );
);