Saludos,
Necesito ayuda para crear secuencias de comandos en un proceso de varios pasos, ya que no puedo abstraer una solución viable para lograr un trabajo de preparación de datos.
Tengo datos de series de tiempo que vienen en varias hojas de cálculo, que contienen varias pestañas, y cada pestaña tiene datos con nombres de columnas que contienen metadatos que contextualizan los datos.
En el siguiente ejemplo, las columnas con "Descriptor" (columnas 1, 3 y 5) en realidad deberían llamarse "Fecha", pero en su lugar contienen Descriptores que se necesitan para el análisis.Además, las columnas de la Unidad (2, 4 y 6) realmente deberían ser datos con nombre pero contener la unidad de medida.
| Grande:Pequeño:Mojado | miligramos | Malo: Bueno: Feo | Hz | Babor:Estribor:Velocidad | ml |
| 15/12/2021 | 0 | 15/12/2021 | 4 | 15/12/2021 | 8 |
| 16/12/2021 | 1 | 16/12/2021 | 5 | 16/12/2021 | 9 |
| 17/12/2021 | 2 | 17/12/2021 | 6 | 17/12/2021 | 10 |
| 18/12/2021 | 3 | 18/12/2021 | 7 | 18/12/2021 | 11 |
Idealmente, la tabla de datos terminada tendría la siguiente estructura.
| Fecha | DescriptorType1 | DescriptorType2 | DescriptorType3 | Unidad | Datos |
| 15/12/2021 | Grande | Pequeño | Húmedo | miligramos | 0 |
| 16/12/2021 | Grande | Pequeño | Húmedo | miligramos | 1 |
| 17/12/2021 | Grande | Pequeño | Húmedo | miligramos | 2 |
| 18/12/2021 | Grande | Pequeño | Húmedo | miligramos | 3 |
| 15/12/2021 | Malo | Bien | Feo | Hz | 4 |
| 16/12/2021 | Malo | Bien | Feo | Hz | 5 |
| 17/12/2021 | Malo | Bien | Feo | Hz | 6 |
| 18/12/2021 | Malo | Bien | Feo | Hz | 7 |
| 15/12/2021 | Puerto | Estribor | Velocidad | ml | 8 |
| 16/12/2021 | Puerto | Estribor | Velocidad | ml | 9 |
Mis intentos de colocar los encabezados de columna en una tabla separada y volver a unirlos con bucles for anidados no han tenido éxito.Aquí hay un código que extrae y prepara los datos del nombre de la columna para los datos de ejemplo incluidos.
Names Default to Here(1);
//Get MainDT column Names
colNames = Data Table("Data") << Get Column Names;
//Create Empty Table
dtCols = New Table("DTCols");
//Put in Columns into the table
dtCols << New Column( "Columns", Character, Values(colNames));
//Label every other row for splitting
dtCols << New Column( "Data", formula( sequence(1,2,1)));
//Remove formula from Data column
dtCols:Data << Delete Formula;
<BR />//New column from which to split from
dtCols << New Column( "Type", formula(
If(
contains(:Columns, "Desc"), "Meta",
"Unit_Raw"
);
);
);
//Deleting formula for handling
dtCols:Type << Delete formula;
//Splitting the row based on the labelling
splitdtCols = dtCols << Split(
Split By( :Type ),
Split( :Columns ),
Sort by Column Property,
Output Table( "SplitDTCols" )
);
//Text to Columns by ":"
splitdtCols << text to columns(delimiter(":"), columns(:Meta));El bucle for anidado (que solo busca volver a colocar la descripción completa en la tabla original) no solo es relativamente lento (esto es necesario para recorrer > 1 millón de entradas), sino que solo escribe los datos que faltan en las columnas.
//Meta column back into Data
For(i = 1, i <= N Items(colNames), i++,
For(j = 1, j <= N Rows(splitdtCols), j++,
//show(splitdtCols:Meta[j]);
If( eval(char(colNames[i])) == eval(char(splitdtCols:Meta[j])),
Data Table("Data") << New Column("Descriptor", set Values(eval(char(splitdtCols:Meta[j]))))
)
)
);Estoy dispuesto a abandonar el enfoque de extraer los datos del nombre de la columna en una tabla separada.Realmente parece que hay un enfoque más simple que me estoy perdiendo.
Esto era exactamente lo que esperaba.Algo sencillo y que se me pasó por alto.Pude implementar esto bastante rápido.
Interactivamente esto es fácil de hacer con un Pila de serie múltiple .
Use Tablas->Apilar y agregue todas las columnas al Apilar columnas lista. Luego haga clic en la casilla de verificación para Pila de serie múltiple . Colocar Número de serie a 2 y no marque Contiguo .

Obtendrás una tabla como esta:

Renombrar el Datos columna a Fecha y el Etiqueta 2 columna a Unidades .

Luego, puede usar Cols->Utilities-> Texto a Cols... para dividir la columna Etiqueta en tres columnas usando dos puntos (":") como delimitador.

Obtendrás esto:

Si necesita crear un script para esto, porque es algo que necesita automatizar o lo hace mucho, puede obtener el script para el script Stack from Source:
stacked_dt = Data Table( "445470" ) << Stack(
columns(
:"Big:Small:Wet"n, :mg, :"Bad:Good:Ugly"n, :Hz, :"Port:Starboard:Speed"n,
:mL
),
Source Label Column( "Label" ),
Stacked Data Column( "Data" ),
Number of Series( 2 )
);
Necesitarás usar el < mensaje para cambiar los nombres de las columnas.
stacked_dt:"Data" << Set Name( "Date" );
stacked_dt:"Label 2" << Set Name( "Units" );
Finalmente, Text to Columns también admite secuencias de comandos.
stacked_dt << Text To Columns(
delimiter( ":" ),
columns( :Label )
);