Saludos,
Necesito ayuda para programar un proceso de varios pasos, ya que no puedo abstraer una solución viable para lograr algún trabajo de preparación de datos.
Tengo datos de series de tiempo que vienen como varias hojas de cálculo, que contienen varias pestañas, y cada pestaña tiene datos con nombres de columna que contienen metadatos que contextualizan los datos.
En el siguiente ejemplo, las columnas con "Descriptor" (columnas 1, 3 y 5) realmente deberían llamarse "Fecha", pero en su lugar deben contener Descriptores que son necesarios para el análisis.Además, las columnas de Unidad (2, 4 y 6) realmente deberían tener nombre pero contener la unidad de medida.
| Grande: Pequeño: Mojado | mg | Malo: Bueno: Feo | Hz | Puerto: 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ña | Mojado | mg | 0 |
| 16/12/2021 | Grande | Pequeña | Mojado | mg | 1 |
| 17/12/2021 | Grande | Pequeña | Mojado | mg | 2 |
| 18/12/2021 | Grande | Pequeña | Mojado | mg | 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 ciclo for anidado (que solo busca volver a poner 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 faltantes 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 siento que me falta un enfoque más simple.
Interactivamente, esto es fácil de hacer con un Pila de varias series .
Use Tablas-> Apilar y agregue todas las columnas al Columnas de pila lista. Luego haga clic en la casilla de verificación para Pila de varias series . Colocar Numero de Series a 2 y no marques Contiguo .

Obtendrás una tabla como esta:

Cambiar el nombre del Datos columna a Fecha y el Etiqueta 2 columna a Unidades .

Luego, puede usar Cols-> Utilities-> Texto a columnas ... 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 << Establecer nombre 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 es programable.
stacked_dt << Text To Columns(
delimiter( ":" ),
columns( :Label )
);
Esto era exactamente lo que esperaba.Algo sencillo y que se me pasó por alto.Pude implementar esto bastante rápido.