Aquí hay un desafío de programación para todos los nerds de JSL que hay.
Tengo 4 niveles de datos jerárquicos en una tabla que se ve así:

Estoy creando una estructura de árbol jerárquica a partir de estos datos usando el cuadro de árbol que se ve así:

Mi código crea esta salida en aproximadamente 40 segundos. ¿Hay una manera mas rápida? Intenté varios enfoques y crear subconjuntos parecía ser el más rápido. Aquí está mi código:
dt = data table ("AE Levels");
ae_tree = {};
e0 = hp time();
// Get unique level 1 values
summarize(dt, level1_list = by(:Level 1));
for (i = 1, i <= nitems(level1_list), i++,
caption("Processing Level1 " || char(i));
wait(0);
level1_rows = dt << get rows where(:Level 1 == level1_list[i]);
// Create a tree node for this level
level1_node = tree node("Level 1: " || level1_list[i]);
// Make a subset of this level1's values
dt1 = dt << subset(private, rows(level1_rows));
// Get unique level 2 values for this value of level 1
summarize(dt1, level2_list = by(:Level 2));
for (k = 1, k <= nitems(level2_list), k++,
// Create a tree node for this level
level2_node = tree node("Level 2: " || level2_list[k]);
level2_rows = dt << get rows where(:Level 2 == level2_list[k]);
dt2 = dt << subset(private, rows(level2_rows));
// Get unique level 3 values for this value of level 2
summarize(dt2, level3_list = by(:Level 3));
for (m = 1, m <= nitems(level3_list), m++,
// Create a tree node for this level
level3_node = tree node("Level 3: " || level3_list[m]);
l3_rows = dt << get rows where(:Level 3 == level3_list[m]);
dt3 = dt << subset(private, rows(l3_rows));
// Get unique level 4 values for this value of level 3
summarize(dt3, l4_list = by(:Level 4));
close(dt3, nosave);
for (n = 1, n <= nitems(l4_list), n++,
// Create a tree node for this level
l4_node = tree node("Level 4: " || l4_list[n]);
// Add the level 4 node to the level 3 node
level3_node << append(l4_node);
);
// Add the level 3 node to the level 2 node
level2_node << append(level3_node);
);
close(dt2, nosave);
// Add the level 2 node to the level 1 node
level1_node << append(level2_node);
);
close(dt1, nosave);
insertinto(ae_tree, level1_node);
);
caption(remove);
wait(0);
e1 = hp time();
show((e1 - e0) / 1000000);
nw = new window("AE Tree",
mtree = tree box(ae_tree, Size( 1000, 500 ),
<< Set Max Size( 2000, 4000 ),
<< Set AutoStretching( 1, 1 )
)
);
Creo que sí ... Puede que no lo haya mirado lo suficiente, pero si esto tiene sentido, es aproximadamente 10 veces más rápido ... este es el bucle más interno ... el bucle externo también lo necesita. LinkToOriginalDataTable no parecía ayudar en absoluto, lo cual fue una sorpresa, pero usar los subconjuntos más pequeños para una mayor subconjunto ayudó mucho.
l3_rows = dt2 << obtener filas donde (: Nivel 3 == nivel3_lista [m]);
dt3 = dt2 << subconjunto (privado, filas (l3_rows), LinkToOriginalDataTable (1) );
// Obtenga valores únicos de nivel 4 para este valor de nivel 3
resumir (dt3, l4_list = by (: Nivel 4));
(e1 - e0) / 1000000 = 3.226879;
Gracias Craige, tu solución cae en la categoría de "por qué no pensé en eso". Tiene demasiado sentido!