Concatenar varias tablas con diferente orden de columnasEquipo,
Tengo 5 archivos csv, cada uno con 200 columnas (no todos los archivos tienen el mismo número de columnas). Cada archivo tiene columnas en diferente orden. Quiero escribir un script que permitirá al usuario seleccionar los 5 archivos, luego combinarlos (eliminando columnas que no coinciden) y guardar el archivo csv combinado en la ubicación requerida. Quiero usar un comando similar a (datos = Abrir (Seleccionar archivo ("Elegir el archivo", x)), x es el directorio), para seleccionar los archivos.
Gracias
Re: Concatenar varias tablas con diferente orden de columnasGracias @txnelson
Siempre eres de gran ayuda.Re: Concatenar varias tablas con diferente orden de columnasAquí hay una reelaboración del script, seleccionando todos los archivos que se concatenarán en una selección y luego ejecutando un pequeño script para juntarlos, manteniendo solo las columnas que encuentren una coincidencia. Lo he creado según sus especificaciones, sin embargo, se puede cambiar fácilmente para permitir la concatenación de cualquier número de archivos.
Names Default To Here( 1 );
inputDirectory = "C:\";
// Select the files to be read in......this can be any number of files
filePath = Pick File(
"Choose the File to be Concatenated to:",
inputDirectory,
{"CSV Files|csv;", "All Files|*"},
1,
0,
""
);
// Open the first file
dtMain = Open( filePath, invisible );
files = Pick File(
"Choose the Additional 4 Files to Read In:",
inputDirectory,
{"CSV Files|csv;", "All Files|*"},
1,
0,
"",
multiple
);
// Validate that files have been read in
If( Try( N Items( files ), 0 ) == 4,
Dialog( "Incorrect number of files were read in."
"Only 4 additional files can be read in");
Throw( "Incorrect number of files were read in" );
);
// Read in the remaining files and process them
For( i = 2, i <= N Items( Files ), i++,
Try( dtConCat = Open( Files[i], invisible ) );
mainColList = dtMain << Get Column Names( string );
conCatColList = dtConCat << Get Column Names( string );
// Delete the columns in the dtConCat table that do not exist in the dtMain table
delList = {};
For( k = 1, k <= N Items( conCatColList ), k++,
If( N Rows( Loc( mainColList, conCatColList[k] ) ) == 0,
Insert Into( delList, conCatColList[k] )
)
);
If( N Items( delList ) > 0,
dtConCat << delete columns( delList )
);
// Delete the columns in the dtMain table that were not found in the dtConCat table
delList = {};
For( k = 1, k <= N Items( mainColList ),
k++,
If( N Rows( Loc( conCatColList, mainColList[k] ) ) == 0,
Insert Into( delList, mainColList[k] )
)
);
If( N Items( delList ) > 0,
dtMain << delete columns( delList )
);
// If any columns still remain in the two tables, then concatenate them together
If( N Cols( dtMain ) > 0 & N Cols( dtConCat ) > 0,
dtMain = dtMain << Concatenate( dtConCat, Append to First Table )
);
// Close the no longer needed file
Close( dtConCat, nosave );
);
// Make the main file visible
dtMain << show window( 1 );
Re: Concatenar varias tablas con diferente orden de columnas@Rajat ,
No entiendo por qué necesitarías crear una nueva tabla. Yo haría algo como esto.
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
OriginalColOrder = dt << Get Column Names("string");
dt << Reorder By Name();
SortedColOrder = dt << Get Column Names("string");
Show(OriginalColOrder);
Show(SortedColOrder); Las listas le proporcionan tanto el orden ordenado como el orden original. Además, comparta lo que ha probado hasta ahora, para que sea más fácil ver hacia dónde se dirige. No puedo entender exactamente qué ha intentado hasta ahora y en qué está fallando. Si no puede compartir sus datos, intente crear algunos datos de muestra, para que sea fácil para todos recrear los problemas y guiarlo.
Re: Concatenar varias tablas con diferente orden de columnas@uday_guntupalli
¿Puede ayudarme a escribir la sintaxis para guardar el orden original y reordenar la tabla final con el orden guardado?
GraciasRe: Concatenar varias tablas con diferente orden de columnas@Rajat ,
dt << Reorder By Name();
Re: Concatenar varias tablas con diferente orden de columnasGracias @uday_guntupalli
Si podemos reordenar las columnas y hacer que tengan el mismo orden. Después de eso concatenaremos todas las tablas.
¿Pueden ayudarme a escribir la sintaxis para reordenar las columnas de todas las tablas según la primera tabla? Luego usaremos el comando concatenar en un bucle. Si no es posible, podemos guardar el orden de las columnas originales de la primera tabla, luego reordenar todas las tablas con su nombre y luego concatenarlas en un bucle. Finalmente, reordenaremos la tabla final según el orden de columnas guardado anteriormente.
@Craige_Hales @txnelson ¿Tiene alguna solución para este problema?
Gracias. Agradezco tu ayuda.Re: Concatenar varias tablas con diferente orden de columnas@Rajat ,
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
Una matriz asociativa tiene una relación o mapeo uno a uno. Entonces, una vez que construimos una matriz asociativa, la segunda línea intenta extraer las claves únicas en el mapa de la matriz asociativa. En cuanto al bloque If, piense en la teoría de conjuntos, cuando i = 1, estamos asignando las claves únicas de Associative Array 1 al resultado. A partir de ahí, lo interconectamos repetidamente con otras matrices asociativas para finalmente llegar a una lista que solo tendrá elementos que sean comunes a todas las matrices asociativas.
Select( :name, :age, :sex, :height, :weight ),
By Row Number
Este fue un error tipográfico de mi ejemplo. Seleccionar (CommonItems) sería apropiado.
No sé si Concatenate funcionará, puedes intentarlo
Re: Concatenar varias tablas con diferente orden de columnas@uday_guntupalli
Gracias por tu gran ayuda.
tengo pocos comentarios
- Todas las tablas tienen diferente número de filas.
- Quiero concatenar (el número de filas en la tabla final será la suma del número de filas de la tabla individual) las tablas para no unirlas. ¿El bucle de concatenación funcionará igual?
Además, ¿podría ayudarme a comprender los siguientes comandos?
- En bucle para encontrar nombres de columnas comunes. ¿Puedes explicar las siguientes líneas?
ThisListAsAA <SPAN class="token operator">=</SPAN> <SPAN class="token function">Associative Array</SPAN><SPAN class="token punctuation">(</SPAN>ThisList<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
ThisListAsAAKeys <SPAN class="token operator">=</SPAN>ThisListAsAA <SPAN class="token operator"><</SPAN><SPAN class="token operator"><</SPAN><SPAN class="token messages"> Get Keys</SPAN><SPAN class="token punctuation">;</SPAN>
<SPAN class="token function">If</SPAN><SPAN class="token punctuation">(</SPAN>i <SPAN class="token operator">==</SPAN> <SPAN class="token number">1</SPAN><SPAN class="token punctuation">,</SPAN>
CommonItems <SPAN class="token operator">=</SPAN> ThisListAsAAKeys<SPAN class="token punctuation">;</SPAN>
<SPAN class="token punctuation">,</SPAN>
<SPAN class="token comment">// else </SPAN>
CommonItems <SPAN class="token operator"><</SPAN><SPAN class="token operator"><</SPAN><SPAN class="token messages"> Intersect</SPAN><SPAN class="token punctuation">(</SPAN>ThisListAsAAKeys<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
<SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">;</SPAN>
Por lo que entendí en " Esta lista como AA " , " Esta lista "se almacenará como una matriz asociativa. Por favor ayuda a entender las siguientes dos líneas. - En bucle para unir las tablas, ¿puede explicar las siguientes líneas?
Select<SPAN class="token punctuation">(</SPAN> <SPAN class="token punctuation">:</SPAN>name<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>age<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>sex<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>height<SPAN class="token punctuation">,</SPAN> <SPAN class="token punctuation">:</SPAN>weight <SPAN class="token punctuation">)</SPAN><SPAN class="token punctuation">,</SPAN>
By Row Number
No hay columnas con nombres de columna: nombre,: edad, etc. y manualmente no podemos escribir para seleccionar columnas porque la cantidad es enorme. Además, no podemos unirnos por número de fila ya que el número de filas es diferente y queremos concatenar la tabla, no unirla.
Gracias
Re: Concatenar varias tablas con diferente orden de columnas@Rajat ,
Estoy asumiendo (no sé qué tan válido es) que tienes el mismo número de filas.
// Define Your Directory and a list to hold File Paths
MyDirectory = "C:\" ;
nFiles = 5;
MyFilePaths = {};
ColNamesListOfList = {};
OpenDts = {};
// Test if Directory exists and get all file paths
Try( If(Directory Exists(MyDirectory),
for(i = 1 , i <= nFiles, i ++,
FilePath = Pick File( "Select File", MyDirectory);
Insert Into(MyFilePaths,FilePath);
);
,
// else
Throw()
),
"Unable to Open File";
);
// Get List of All Column Names
for(i = 1, i <= nFiles, i++,
OpenDts[i] = Open(MyDirectory || "\" || FilePath[i],"Invisible");
ColNames = OpenDts[i] << Get Column Names("String");
Insert Into(ColNamesListOfList,ColNames);
);
// Find Common Column Names
for(i = 1, i <= nFiles, i++,
ThisList = ColNamesListOfList[i];
ThisListAsAA = Associative Array(ThisList);
ThisListAsAAKeys =ThisListAsAA << Get Keys;
If(i == 1,
CommonItems = ThisListAsAAKeys;
,
// else
CommonItems << Intersect(ThisListAsAAKeys);
);
);
// Concatenate
for(i = 1, i <= nFiles, i++,
If(i == 1,
dt_Results = OpenDts[i];
,
dt_Results << Join(With( OpenDts[i]),
Merge Same Name Columns,
Select( :name, :age, :sex, :height, :weight ),
By Row Number // assuming that the tables have the same number of rows
);
);
); Re: Concatenar varias tablas con diferente orden de columnasGracias Uday. Quiero concatenar las columnas comunes.Re: Concatenar varias tablas con diferente orden de columnas@Rajat ,
Analizando el problema que ha descrito, dividámoslo en varios pasos.
Paso 1: Seleccionar los archivos deseados - usando Seleccionar archivo ()
),
"Unable to Open File";
); // Define Your Directory and a list to hold File Paths
MyDirectory = "C:\" ;
nFiles = 5;
MyFilePaths = {};
OpenDts = {};
// Test if Directory exists and get all file paths
Try( If(Directory Exists(MyDirectory),
for(i = 1 , i <= nFiles, i ++,
FilePath = Pick File( "Select File", MyDirectory);
Insert Into(MyFilePaths,FilePath);
); <BR /> , <BR /> // else<BR /> Throw()<BR />
Paso 2: recorrer los archivos, abrir y concatenar columnas comunes
Aquí tengo una pregunta para ti. ¿Hay una lista de columnas que espera en la tabla final (o) son solo las columnas comunes en los 5 archivos csv?