Hola,
Tengo 2 tablas (Tabla1 y Tabla2), ambas consultadas desde bases de datos.
Necesito actualizar la Tabla1 con la Tabla2 haciendo coincidir las columnas (:match).
El problema es:
- Obtengo contenido coincidente para la Tabla1 con una expresión regular de la base de datos con (a veces) este formato: “XXXX-YY-ZZZ”.
- Obtengo contenido coincidente para la Tabla 2 de otra base de datos con un formato diferente pero consistente: “XXXXYYZZZ”.
Puedo usar If() y Subsitute() manualmente para deshacerme de “-“ en un paso adicional, pero necesito repetir una gran cantidad de actualizaciones de tablas con el formato de columna que normalmente coincide. Me gustaría evitar esa ruta si es posible.
Veo dos posibles soluciones:
1- ¿Existe una forma elegante dentro de Update() que pueda buscar la “coincidencia más cercana” entre columnas ignorando caracteres específicos?
2- ¿Hay alguna manera de hacer coincidir una cadena específica de caracteres con expresiones regulares como “XXXX-YY-ZZZ” pero mostrar solo “XXXXYYZZZ”? De esta manera puedo corregir el formato de :match en la tabla 1
Si tienes otro enfoque en mente, me encantaría escucharlo.
A continuación se muestra un ejemplo de script con el paso “extra”
Gracias,
- el predicador
Names Default To Here( 1 );
dt1 = New Table( "Table1",
Add Rows( 20 ),
New Column( "match", // format "XXX-YY-ZZZ"
Character,
"Nominal",
set values({"786-79-6822", "413-31-2411", "286-37-3500", "985-96-1683", "641-67-8572","537-38-5509", "136-71-5147", "965-59-8232", "141-62-8885", "212-98-2829","330-28-2219", "938-39-3349", "203-47-1149", "310-16-8252", "273-85-3049","543-87-1778", "784-24-3481", "708-81-6285", "902-33-5331", "763-59-8837"})
),
New Column( "Value1",
Character,
"Nominal",
set values ( {"1.7826391133", "3.4239116441", "0.1994181285", "3.5850992007", "1.8049403103", "2.3814269388", "2.3045256995", "3.3546657711", "2.341782487", "1.9017582694", "1.5864833118", "1.3739423649", "2.0963420644", "0.4244481763", "3.6469046306", "3.1553423936", "0.6822735481", "3.9464927437", "0.7582216617", "0.9802403664"})
)
);
dt2 = New Table( "Table2",
Add Rows( 20 ),
New Column( "match", // format "XXXYYZZZ"
Character,
"Nominal",
set values({"537385509", "708816285", "938393349", "543871778", "286373500", "902335331", "784243481", "273853049", "641678572", "203471149", "985961683", "413312411", "786796822", "965598232", "136715147", "763598837", "330282219", "212982829", "141628885", "310168252"}
)
),
New Column( "Value2",
Character,
"Nominal",
set values ( {"1.7489787", "1.763834", "3.0609319", "0.7657611", "2.0515768", "0.8648471", "1.0966909", "1.5494098", "2.7582114", "1.1778722", "2.8651535", "2.3157859", "4.3617672", "0.7137677", "1.1055379", "1.8654949", "4.0616821", "2.3122891", "1.9496742", "2.3774745"})
)
);
// I would like to remove this extra step (it doens't apply on all tables I need to loop through...
dt1 << new column ("Column 3",Character,"Nominal",formula(substitute(:match,"-","")));
// ...and make the Update() more robust with a "nearest match", not "exact "match"
dt1 << Update (
with (dt2),
match columns (Column("Column 3") == Column("match"))
)Hola Jim,
Si agrego el paso de eliminar el "-" con replaced by ...
Si lo hago con mis datos reales, también funciona, pero me gustaría evitar este paso, porque no todas mis Tabla1 tienen el "-" extra en la columna :match
Si puede usar Substitute(), hágalo. La función de actualización/unión de JMP no tiene opciones de "más cercano" para unir (y esto es más difícil ya que lo está haciendo en función de cadenas donde la pregunta es "cuál es el más cercano"). También puede usar Transformar columnas si no desea crear nuevas (lograr que esto funcione inicialmente puede requerir un poco más de esfuerzo).
// Update data table
Data Table("Big Class") << Update(
With(Data Table("Untitled")),
Match Columns(
Transform Column("Concatenate[name]", Character, Formula(Concat(:name))) =
:Column 1
)
);
Cree un script para la función "Agrupar valores similares" en la plataforma Recode con JSL y necesita unir dos tablas en función de cadenas no idénticas (¿usar expresiones regulares?) en JSL (su publicación) puede brindar algunas ideas sobre cómo unir por la coincidencia de cadena más cercana si realmente desea ir por esa ruta.
Hola Jim,
Mi limitación era que no todos los casos necesitaban esta transformación, por lo que quería que mi script fuera más inteligente. Pero encontré una solución:
Busco "-" con un IF() CONTAINS(), y si es verdadero, hago un doble REGEX(): el primero para buscar el patrón a coincidir, y el segundo para aplicar la transformación (quitar "-").
No es súper elegante pero funciona y es bastante robusto.
Gracias de nuevo, como siempre.:)
- el predicador
- el predicador
Hola jarmo,
Encontré algunos problemas con el enfoque de la última vez: Necesito unir dos tablas basadas en cadenas no idénticas (¿Usar expresiones regulares?) en JSL
La tasa de falsos positivos fue un pequeño problema. Si no hay una coincidencia "más cercana", necesito dejar la celda vacía en lugar de forzar una coincidencia, que era el espíritu de este enfoque.
En lugar de eso, resolví este problema como se describe en la respuesta a Jim: use una expresión regular doble con una condición. De esa manera, evito los falsos positivos.
Pero muchas gracias por participar como siempre.
- el predicador