Ho due tabelle che voglio unire con un timestamp, tuttavia, i timestamp non vengono registrati esattamente nello stesso momento. Pertanto, desidero unire tutti i timestamp che si trovano entro 5 minuti l'uno dall'altro. Se il timestamp non ha un timestamp corrispondente nell'altra tabella, desidero comunque conservare i dati della riga. C'è un modo semplice per farlo in JSL?
È possibile creare una colonna formula in ogni tabella di dati che arrotonda la colonna timestamp ai 5 minuti più vicini e quindi utilizzare tali colonne per il join.In JMP 14, se si fa clic con il pulsante destro del mouse sull'intestazione della colonna timestamp, quindi si seleziona Nuova colonna formula->Trasforma->Arrotonda..., verrà visualizzata una finestra di dialogo che offre la possibilità di arrotondare per eccesso, per difetto o all'incremento di tempo più vicino desiderato.Se non si dispone di JMP 14, la formula per arrotondare all'intervallo di 5 minuti più vicino sarebbe simile a questa:
Round( :Timestamp / 300 ) * 300
(Notare che 300 è il numero di secondi in 5 minuti).
La finestra di dialogo Tabelle->Generatore query di JMP (o Tabelle->Unisci) dispone di opzioni per mantenere le non corrispondenze e creare una colonna Flag di corrispondenza.
Spero che questo ti aiuti.
Non esiste una piattaforma integrata che eseguirà un join con la corrispondenza fuzzy poiché hai dichiarato di cosa hai bisogno.Tuttavia, JSL può essere utilizzato per ottenere ciò di cui hai bisogno.
Ecco un esempio approssimativo di un modo per scrivere la tua richiesta
Names Default To Here( 1 );
// Create sample data tables
dt1 = New Table( "Data Table 1",
Add Rows( 100 ),
New Column( "DateTime",
Numeric,
"Continuous",
Format( "m/d/y h:m", 19 ),
Input Format( "m/d/y h:m" ),
Formula( Today() + Row() * In Minutes( 5 ) ),
Set Selected
)
);
dt1 << run formulas;
dt1:DateTime << delete formula;
dt2 = dt1 << Subset(
Sampling Rate( 0.25 ),
Selected columns only( 0 ),
output table name( "Data Table 2" ),
link to original table( 0 )
);
Current Data Table( dt2 );
For Each Row( :DateTime = :DateTime + In Minutes( Random Uniform( -100, 100 ) ) );
dt2 << sort( by( :DateTime ), order( ascending ), replace table( 1 ) );
// Create a column in data table 1 for reference
dt1 << New Column( "RowNum", formula( Row() ) );
dt1:RowNum << delete formula;
// Create in data table 2 a column that will hold the row to join to
dt2 << New Column( "Match Row" );
// Loop through data table 2 and find the rows in the first table that match
For( i = 1, i <= N Rows( dt2 ), i++,
checkVal = dt2:DateTime[i];
theRows = dt1 << get rows where(
:Datetime > checkVal - In Minutes( 5 ) & :DateTime < checkVal + In Minutes( 5 )
);
If( N Rows( theRows ) > 0,
minList = {};
For( k = 1, k <= N Rows( theRows ), k++,
Insert Into( minList, Abs( dt1:DateTime[theRows[k]] - checkVal ) )
);
dt2:Match Row[i] = theRows[Loc( minList, Min( minList ) )];
,
dt2:Match Row[i] = 0
);
);
// Join the tables
dt3 = dt1 << Join(
With( dt2 ),
Merge Same Name Columns,
By Matching Columns( :RowNum = :Match Row ),
Drop multiples( 0, 0 ),
Include Nonmatches( 1, 1 ),
Preserve main table order( 1 ),
output table name("Final Table")
);