Analizar la cadena de una columna y llenar otra columnaHola,
Tengo una tabla que contiene ProductName y quiero generar la columna OUTPUT.La columna OUTPUT es una concatenación de ProductID con el número de serie. ¿Cómo analizo con precisión el número de serie y creo la columna SALIDA?
Ejemplos de número de serie:
- 07-08_13 significa número de serie 07, 08, 13
- 09-12 significa número de serie 09, 10, 11, 12
- 01-03_05-08 significa número de serie 01, 02, 03, 05, 06, 07, 08
- 01_04_05-08 significa número de serie 01, 04, 05, 06, 07, 08
- 09_11_13_14 significa Serie # 09,11,13,14

| Nombre del producto | PRODUCCIÓN |
| AABBCC_07-08_13 | AABBCC-07 |
| AABBCC_07-08_13 | AABBCC-08 |
| AABBCC_07-08_13 | AABBCC-13 |
| AABBCC_09-12 | AABBCC-09 |
| AABBCC_09-12 | AABBCC-10 |
| AABBCC_09-12 | AABBCC-11 |
| AABBCC_09-12 | AABBCC-12 |
| EEFFGG_02 | EEFFGG-02 |
| HHIIJJ_01-07 | HHIIJJ-01 |
| HHIIJJ_01-07 | HHIIJJ-02 |
| HHIIJJ_01-07 | HHIIJJ-03 |
| HHIIJJ_01-07 | HHIIJJ-04 |
| HHIIJJ_01-07 | HHIIJJ-05 |
| HHIIJJ_01-07 | HHIIJJ-06 |
| HHIIJJ_01-07 | HHIIJJ-07 |
| KKLLLMM_01-03_05-08 | KKLLLMM-01 |
| KKLLLMM_01-03_05-08 | KKLLLMM-02 |
| KKLLLMM_01-03_05-08 | KKLLLMM-03 |
| KKLLLMM_01-03_05-08 | KKLLLMM-05 |
| KKLLLMM_01-03_05-08 | KKLLLMM-06 |
| KKLLLMM_01-03_05-08 | KKLLLMM-07 |
| KKLLLMM_01-03_05-08 | KKLLLMM-08 |
| NNOOPP_01_04_05-08 | NNOOPP-01 |
| NNOOPP_01_04_05-08 | NNOOPP-04 |
| NNOOPP_01_04_05-08 | NNOOPP-05 |
| NNOOPP_01_04_05-08 | NNOOPP-06 |
| NNOOPP_01_04_05-08 | NNOOPP-07 |
| NNOOPP_01_04_05-08 | NNOOPP-08 |
| QQRRSS_09_11_13_14 | QQRRSS_09 |
| QQRRSS_09_11_13_14 | QQRRSS_11 |
| QQRRSS_09_11_13_14 | QQRRSS_13 |
| QQRRSS_09_11_13_14 | QQRRSS_14 |
Tabla de datosScriptingRe: analizar la cadena de una columna y llenar otra columnaLo más probable es que pueda escribir una fórmula con Lag para hacer eso (o un script con JSL), pero también puede intentar hacerlo de forma interactiva, pero se necesitan bastantes pasos:
1. Seleccione la columna ProductName
2. Vaya a Cols / Utilities / Text To columnas y use - y _ como delimitadores.

3. Vaya a Tablas y pila y agregue todo lo demás además de la primera columna a la selección de Columnas de pila


5. Quitar la columna Etiqueta
6. Seleccione las dos columnas que quedan y vaya a Filas / Selección de filas / Seleccionar filas duplicadas y elimine esas filas

7. Seleccione una celda con un valor vacío y elija Seleccionar celdas coincidentes y elimine esas filas.
8. Ahora elija ambas columnas y haga clic con el botón derecho en el encabezado de la columna y cree la fórmula

9. Abra la fórmula recién creada y cambie, a _

10. Cambiar el nombre y eliminar columnas / fórmulas
11. Si necesita ProductName allí, debería poder mantenerlo allí si no lo elimina accidentalmente en el primer paso como lo hice

Si tiene que tener - o _ dependiendo del número de serie, lo más probable es que pueda manejarlo en la fórmula de concatenar
Editar: Verifiqué la pregunta con un poco más de precisión y esto es un poco más complicado de lo que mostré aquí. Tendrá que agregar cálculos para algunos de los números de serie porque están entre números. Esta solución no funcionará en esos porque algunas filas se eliminarán cuando se eliminen los duplicados.
Re: analizar la cadena de una columna y llenar otra columnaHola @cchueng ,
Hay un par de maneras. Algunos se basan en secuencias de comandos (busque una respuesta de alguien que sugiera esto con un ejemplo) o puede usar rondas sucesivas de Texto a columnas (el ejemplo se encuentra aquí Resuelto: ¿Cómo puedo dividir el texto de una columna en varias columnas? - Comunidad de usuarios de JMP) Luego, puede concatenar las columnas deseadas seleccionándolas y luego usar una fórmula de columna o usar la opción Nueva columna de fórmula después de hacer clic derecho en una de las columnas seleccionadas. Busque las opciones de Carácter para concat.La fórmula de la columna es más flexible y le ofrece muchas opciones; consulte la ayuda sobre este tema ( Crear fórmulas en JMP )
Espero que eso te dé alguna dirección.
Mejor,
Re: analizar la cadena de una columna y llenar otra columna@jthi ,
Me ganaste.
Tu explicación es más detallada y también en lo que estaba pensando.
Re: analizar la cadena de una columna y llenar otra columnaOh, tienes razón. el - se interpreta como un rango y el _ se interpreta como un delimitador verdadero de elementos
Re: analizar la cadena de una columna y llenar otra columnaGracias, pero prefiero un jsl en lugar del delimitador interactivo. Su método no abordó el escenario cuando el número de serie 09-12. Debería generar filas como las siguientes. No solo AABBCC-09 y AABBCC-12. El "-" significa "a" rango de significado. Entonces 09-12 significa 09, 10, 11, 12.
| AABBCC_09-12 | AABBCC-09 |
| AABBCC_09-12 | AABBCC-10 |
| AABBCC_09-12 | AABBCC-11 |
| AABBCC_09-12 | AABBCC-12 |
Re: analizar la cadena de una columna y llenar otra columnaOk, esto podría funcionar. Requiere JMP16 debido al uso de For Each (se puede reemplazar con For para otras versiones. Esta es una solución con mucho script, con pocos o ningún comentario y requerirá una tabla de inicio específica para funcionar (necesita la columna OUTPUT).
Names Default To Here(1);
dt = New Table("Untitled 4993",
Add Rows(32),
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14"}
)
),
New Column("OUTPUT",
Character(16),
"Nominal",
Set Values({"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""})
)
);
Summarize(dt, uniqProd = by(:ProductName));
valList = {};
For Each({prod}, uniqProd,
prodPart = Word(1, prod, "_");
serialPart = Substr(prod, Contains(prod, "_") + 1); //remove start
possibleRanges = Words(serialPart, "_"); //if they contain -
For Each({val}, possibleRanges,
If(Contains(val, "-"), //range
rangeVals = Words(val, "-");
For Each({val1}, Index(Num(rangeVals[1]), Num(rangeVals[2])),
valToAdd = Substr("0", Length(Char(val1))) || Char(val1);
Insert Into(valList, prodPart || "-" || valToAdd)
);
,
Insert Into(valList, prodPart || "-" || Substr("0", Length(Char(val))) || Char(val))
)
);
);
dt[0,"OUTPUT"] = valList;Me pregunto si algo como esto se podría hacer "fácilmente" con la propia coincidencia de patrones de JMP. @Craige_Hales
Re: analizar la cadena de una columna y llenar otra columnaHola Chris,
Tengo un script que abordará algunos de los ProductName y, a veces, analizará incorrectamente. ¿Puede revisar y agregar códigos para abordar los ProductNames que no funcionan hasta ahora?
Funcionará para los siguientes ejemplos:
EEFFGG_02
HHIIJJ_01-07
KKLLLMM_01-03_05-08
No funcionará todavía para los siguientes ejemplos:
AABBCC_07-08_13
NNOOPP_01_04_05-08
QQRRSS_09_11_13_14
dt=current data table();
(dt << New Column( "ProductID", Character )) << Set Selected;
(dt << New Column( "OUTPUT", Character )) << Set Selected;
//Parse string in ProductName column
For Each Row(
dt,
//Assign the ProductID value
:ProductID = Word( 1, :ProductName, "_-" ); //"_"
//If the ProductName changes, capture the start and end
If( :ProductName != Lag( :ProductName, 1 ),
start = Num( Word( 2, :ProductName, "_-" ) );
end = Num( Word( 3, :ProductName, "_-" ) );
);
//Assign the OUTPUT value
:OUTPUT = :ProductID || "-" || Repeat( "0", 2 - Length( Char( start ) ) ) || Char( start );
//After end value & there is an _, set start to value after _
If( start == end & Contains( :ProductName, "_"),
start = Num( Word(-2, :ProductName, "_-" ) ),
start++);
);
Re: analizar la cadena de una columna y llenar otra columnaHola jthi,
Gracias por el guión, pero mi mesa es realmente dinámica. Cada día, extraeré esta tabla de una base de datos con un rango de fechas diferente y aparecerán diferentes conjuntos de ProductName. Por tanto, no siempre son 32 filas. Su secuencia de comandos casi puede funcionar, pero ¿puede abordar el tamaño de la matriz? Gracias.
Re: analizar la cadena de una columna y llenar otra columnaDebería ser bastante fácil. ¿Tiene tantas filas en los datos extraídos como números de serie?
Re: analizar la cadena de una columna y llenar otra columnaHola jthi,
Sí, el número de filas coincidió con el número de números de serie.
Re: Analizar cadena de una columna y llenar otra columnaSi ese es el caso, ya debería ser capaz de manejarlo. Hice pequeñas modificaciones (creación de la columna OUTPUT si falta). Actualmente se basa en el hecho de que la tabla de datos está ordenada por ProductNames, lo que podría causar problemas en algún momento, o luego puede asegurarse de que la tabla de entrada esté ordenada (solución más fácil).
Debería poder usar For Each parte incluso sin tabla de datos siempre que tenga una variable de lista llamada uniqProd que tenga ProductNames. Después de eso, solo está descubriendo cómo agregar valores a la tabla de datos.
Names Default To Here(1);
//Test table
/*
dt = New Table("Untitled 4993",
Compress File When Saved(1),
New Column("ProductName",
Character,
"Nominal",
Set Values(
{"AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_07-08_13", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "AABBCC_09-12", "EEFFGG_02",
"HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "HHIIJJ_01-07", "KKLLLMM_01-03_05-08",
"KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08", "KKLLLMM_01-03_05-08",
"NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08", "NNOOPP_01_04_05-08",
"QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14", "QQRRSS_09_11_13_14"}
)
)
);
*/
dt = Current Data Table();
Summarize(dt, uniqProd = by(:ProductName));
valList = {};
For Each({prod}, uniqProd, //loop for each ProductName
prodPart = Word(1, prod, "_");
serialPart = Substr(prod, Contains(prod, "_") + 1); //remove start
possibleRanges = Words(serialPart, "_"); //if they contain -
For Each({val}, possibleRanges, //Loop for serialnumber inside the ProductName
If(Contains(val, "-"), //range
rangeVals = Words(val, "-");
For Each({val1}, Index(Num(rangeVals[1]), Num(rangeVals[2])),
valToAdd = Substr("0", Length(Char(val1))) || Char(val1);
Insert Into(valList, prodPart || "-" || valToAdd)
);
,
Insert Into(valList, prodPart || "-" || Substr("0", Length(Char(val))) || Char(val))
)
);
);
//if starting table doesn't have OUTPUT column create it
If(!Contains(dt << Get Column Names("String"), "OUTPUT"),
dt << New Column("OUTPUT", Character, "Nominal");
);
//dt[0,"OUTPUT"] = valList; subscripting, maybe a bit more difficult to understand
dt:OUTPUT << Set Values(valList);
Versión simplificada de lo que intenta hacer el script:
1. El script obtiene todos los valores únicos en la columna ProductName
2. Script loops sobre cada uno de ellos en dos partes For Each loop
3. El primer bucle recorre los valores únicos y los divide en partes de producto y número
4. La parte del número de serie vuelve a repetirse para dividirla en valores individuales. Estos valores únicos se concatenan con la parte Producto y luego la cadena se inserta en la lista valList (este 4. no es exactamente tan simple como lo expliqué aquí).
5. Después de que ambos bucles hayan terminado, debería tener una lista con todos los números de serie posibles. La parte del producto estará en orden alfabético.
6. Esta lista luego se agrega a OUTPUT si existe, si no existe, primero se crea.
Re: Analizar cadena de una columna y llenar otra columnaHola Jthi,
Su secuencia de comandos no funcionará si mi ProductName es una combinación de caracteres y números. Adjunto una tabla. Así es como se verá la mayor parte de mi productName. Gracias por ayudarme.