¿Cómo agrego datos de una tabla a otra en función de la distancia?Tengo dos tablas de datos para dos conjuntos de mediciones en la oblea. Hay cuatro columnas en cada tabla, X, Y que representan la ubicación de las mediciones y dos columnas de datos de medición para cada tabla. Las mediciones no se recopilan exactamente desde las mismas posiciones (X, Y) de la oblea. Me gustaría actualizar (agregar columnas adicionales de la otra tabla) cualquiera de las tablas en función de la proximidad de las ubicaciones de medición. Para ser más claro, me gustaría tener una tabla combinada (8 columnas en total) basada en la coincidencia de X1, Y1 con el punto más cercano en X2 e Y2. Vea la imagen que cargué. Sé que la función de distancia probablemente se pueda utilizar para hacer una matriz de todas las distancias desde un X, Y dado, pero no estoy seguro de cómo escribir el código jsl para calcular la tabla actualizada para mí.
Automatización y scriptingCombinación y limpieza de datosVentanasRe: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Consulte las siguientes funciones además de Distancia
Luego, agregue un índice basado en filas a su tabla "principal", utilice uno de estos para encontrar el índice más cercano (básicamente, fila), agréguelo a su segunda tabla y finalmente use actualizar/unir para combinar las tablas.
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Basándome en los enlaces de @jthi , creo que esto hace lo que quieres.
dt1=New Table( "Table 1",
Add Rows( 20 ),
New Column( "x",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() )
),
New Column( "y",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() )
),
Set Row States( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0] )
);
dt2=New Table( "Table 2",
Add Rows( 20 ),
New Column( "x",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() ),
Set Display Width( 120 )
),
New Column( "y",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() ),
Set Selected,
Set Display Width( 118 )
),
Set Row States( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0] )
);
M1 = dt1 << GetAsMatrix();
MD1=vptree(M1);
M2 = dt2 << GetAsMatrix();
MD2=kdtable(M2);
//returns the nearest point of Table 1 to a point in table 2
//to reverse the look up, make MD1-> MD2 and M2->M1
{rows, dist} = MD1 << K nearest rows( 1, M2);
dt1<<NEW column=""></NEW>Steve
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Hola Steve y Jarmo,
Gracias por las sugerencias. El script también fue útil. Sin embargo, cuando lo ejecuto, no creo que encuentre la distancia más cercana. Por ejemplo, en la primera fila de la Tabla 1 coincide con la fila 8 (distancia de ~1,37) de la Tabla 2, pero hay muchos puntos mucho más cercanos, como la fila número 1 (distancia de 0,69) (sea la distancia sqrt[(x-x0)^2+(y-y0)^2])

Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Creo que confundí las tablas de datos al final del script, prueba esto:
dt1=New Table( "Table 1",
Add Rows( 20 ),
New Column( "x",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() )
),
New Column( "y",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() )
),
Set Row States( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0] )
);
wait(0.0);
dt1:x << suppress eval( true );
dt1:y << suppress eval( true );
dt2=New Table( "Table 2",
Add Rows( 20 ),
New Column( "x",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() ),
Set Display Width( 120 )
),
New Column( "y",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Random Normal() ),
Set Selected,
Set Display Width( 118 )
),
Set Row States( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0] )
);
wait(0.0);
dt2:x << suppress eval( true );
dt2:y << suppress eval( true );
M1 = dt1 << GetAsMatrix();
MD1=vptree(M1);
M2 = dt2 << GetAsMatrix();
MD2=kdtable(M2);
//returns the nearest point of Table 1 to a point in table 2
//to reverse the look up, make MD1-> MD2 and M2->M1
{rows, dist} = MD1 << K nearest rows( 1, M2);
dt2<<NEW column=""></NEW>I virtual linked them and did some visual checks so I believe we are good now
<SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><span class="lia-inline-image-display-wrapper" image-alt="shampton82_0-1724013813741.png" style="width: 400px;"><img src="https://us.v-cdn.net/6038925/uploads/images/67225i8663690D9A1ED800/shampton82_0-1724013813741.png" role="button" title="shampton82_0-1724013813741.png" alt="shampton82_0-1724013813741.png" /></span></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN></SPAN>
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?I still see it is not picking up the closest points: <BR />Names Default To Here( 1 );
Close All(data tables);
Clear Log();
Clear Symbols();
dt1= Open(
"C:\Users\Table 1.jmp");
wait(0.0);
dt1:X1 << suppress eval( true );
dt1:Y1 << suppress eval( true );
dt2= Open(
"C:\Users\Table 2.jmp");
wait(0.0);
dt2:X2 << suppress eval( true );
dt2:Y2 << suppress eval( true );
M1 = dt1 << GetAsMatrix();
MD1=vptree(M1);
M2 = dt2 << GetAsMatrix();
MD2=kdtable(M2);
//returns the nearest point of Table 1 to a point in table 2
//to reverse the look up, make MD1-> MD2 and M2->M1
{rows, dist} = MD1 << K nearest rows( 1, M2);
dt1<<NEW column=""></NEW>Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?dt1=New Table( "Table 1",
Add Rows( 20 ),
New Column( "x",
Formula( Random Uniform(0,10) )
),
New Column( "y",
Formula( Random Uniform(0,10) )
)
);
dt2=New Table( "Table 2",
Add Rows( 64 ),
New Column( "x2",
Formula( floor(row()/8)+1 )
),
New Column( "y2",
Formula( mod(row(),8)+1 )
)
);
// M2 = dt2 << GetAsMatrix();
// better - see below
M2 = dt2[0, {"x2", "y2"}];
MD2=kdtable(M2);
dt1 << New Column( "row_orig",Nominal, Formula( Row() ));
dt2 << New Column( "row_2",Nominal,Formula( Row() ));
dt1 << New Column( "table",Nominal, set each value(1));
dt2 << New Column( "table",Nominal, set each value(2));
wait(0);
// step by step, for each row in dt1, use MD2 to find the closest position in dt2
dt1 << new column("row_2",Nominal, set each value(
pos = Matrix({:x, :y});
(MD2 << K nearest rows( 1, pos))[1][1]));
// concatenate the tables to generate a combined plot
dt2:x2 << set name("x");
dt2:y2 << set name("y");
check = dt1 << Concatenate(dt2);
check << Graph Builder(
Show Control Panel( 0 ),
Variables( X( :x ), Y( :y ), Overlay( :row_2 ), Color( :table ) ),
Elements(
Line( X, Y, Row order( 1 ) ),
Points( X, Y, Overlay( 0 ), Legend( 2 ) )
),
SendToReport(
Dispatch( {}, "400", ScaleBox,
{Legend Model(
2,
Properties( 0, {Marker( "FilledSquare" )}, Item ID( "1", 1 ) ),
Properties( 1, {Marker( "Circle" )}, Item ID( "2", 1 ) )
)}
)
)
);

Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?¡Gracias por limpiar esto por mí @hogi !
Pregunta, ¿puedes explicarme qué hace esta línea de código?
dt1 << new column("row_2",Nominal, set each value(pos = Matrix({:x, :y});(MD2 << K nearest rows( 1, pos))[1][1]));
¡Agradecer!
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Gracias hogi,
Funciona de maravilla, sin embargo, tuve exactamente la misma pregunta que Steve:
¿Puedes explicar la línea?
dt1 << new column("row_2",Nominal, set each value(pos = Matrix({:x, :y});(MD2 << K nearest rows( 1, pos))[1][1]));Además, cuando ejecuto mi versión (leyendo las tablas con cuatro columnas (x, y, datos 1, datos 2) en la Tabla 1 y (x2, y2, datos 3, datos 4)) obtengo la siguiente alerta. Creo que está molesto porque la Tabla 1 y la Tabla 2 tienen más de dos columnas (x, y) que no están en la matriz. Pero si explica la línea, ¡creo que puedo descifrar el resto! Gracias por la ayuda

Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Hola @spinup
Creo que el problema es que mi código asumió que solo tenía los valores x e Y en la tabla. Si comienza con sus tablas que tienen columnas numéricas adicionales, entonces k vecinos más cercanos intenta encontrar el punto más cercano para X, Y, A, B frente a X, Y, C, D.
Creo que es por eso que los códigos @hogi funcionan tan bien si solo se mira X e Y.
Si crearas columnas que no sean X/Y y ejecutaras mi segundo código, funcionaría, solo tendrías que volver a cambiarlas a numéricas una vez que las unieras.
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Algo así es con lo que suelo terminar
Names Default To Here(1);
dt1 = New Table("Table 1",
Add Rows(20),
New Column("x", Numeric, "Continuous", Formula(Random Normal())),
New Column("y", Numeric, "Continuous", Formula(Random Normal()))
);
dt2 = New Table("Table 2",
Add Rows(20),
New Column("x", Numeric, "Continuous", Formula(Random Normal())),
New Column("y", Numeric, "Continuous", Formula(Random Normal())),
New Column("Val", Numeric, Continuous, Formula(Random Normal(2, 100)))
);
m1 = dt1[0, {"x", "y"}];
m2 = dt2[0, {"x", "y"}];
tree = VPTree(m2);
{rows, distances} = tree << K Nearest Rows(1, m1);
dt1 << New Column("Nearest", Numeric, Ordinal, Values(rows));
dt1 << New Column("Distance", Numeric, Ordinal, Values(distances));
dt2 << New Column("Row", Numeric, Ordinal, Values(1::N Rows(dt2)));
/* Depending on the wanted result, using Update might be better */
dt_result = dt1 << Join(
With(dt2),
By Matching Columns(:Nearest = :Row),
Drop multiples(0, 0),
Include Nonmatches(0, 0),
Preserve main table order(1),
Output Table("Result")
);
/*
Close(dt1, no save);
Close(dt2, no save);
*/
Es posible que la operación Unir/K Filas más cercanas se haya realizado en la dirección incorrecta, ya que no verifiqué los resultados.
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Para obtener la matriz con las coordenadas, puedes utilizar subíndices de tabla de datos, como lo hace Jarmo en su ejemplo:
fila = 0 -> todas las filas
columnas: x e y
coordinates as matrix = dt1[0, {"x", "y"}];Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?La documentación de VPTree podría optimizarse.
Tabla KD:

KDTable << K filas más cercanas tiene dos modos:
- predeterminado: tomar las posiciones de entrada como puntos de partida.
-> no apto para nosotros.
- Opcional: utilice una única posición como punto de partida.
-> ¡Sí!
Calculo este punto como pos = Matriz ({:x,:y}) para cada fila y lo proporciono como segundo argumento para las K filas más cercanas.
Los valores de retorno son vectores de filas y distancias. Con [1][1] , puedo obtener primero las filas y luego la primera (y única) entrada.
Desafortunadamente no existe ningún modo que permita proporcionar un conjunto de puntos de partida como entrada.
Árbol VP:
Para las K filas más cercanas no hay documentación real en el Scripting INdex, pero hay un ejemplo directamente en la definición de VPTree:

y hay alguna documentación en la ayuda en línea:


Suena como las mismas dos opciones que para KDTable.
Del ejemplo de @jthi se puede ver que VPTree permite un tercer modo, donde se proporciona un conjunto de posiciones como una matriz.
Esto es un poco sorprendente, pero muy conveniente. 
tree = VPTree(m2);
{rows, distances} = tree << K Nearest Rows(1, m1);
dt1 << New Column("Nearest", Numeric, Ordinal, Values(rows));
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?VPtree << K Nearest Rows(1, matrix of coordinates);
lindo : ):)
Re: ¿Cómo agrego datos de una tabla a otra en función de la distancia?Más ideas:
- deseo relacionado con 1D: agregar unión difusa / fusión asof / unión por columnas que no tienen coincidencias exactas
Acabo de agregar un comentario para considerar dimensiones superiores.
- En casos de aplicación reales, existen coordenadas nominales adicionales como lotes, obleas y variantes. El usuario debe dividir los datos en consecuencia y configurar VPTrees separados para cada "variante". VPTree con groupBy será el siguiente paso lógico.
- Por otro lado, en lugar de utilizar simplemente un valor vecino, el usuario podría preferir interpolar los datos de entrada para obtener valores más significativos. Agrupar por: ¡¡¡muy útil!!! ¿Qué tal interpolar?