J'ai deux tables que je souhaite rejoindre par un horodatage, cependant, les horodatages ne sont pas enregistrés exactement au même moment. Par conséquent, je souhaite joindre tous les horodatages situés à moins de 5 minutes les uns des autres. Si l'horodatage n'a pas d'horodatage correspondant dans l'autre table, je souhaite quand même conserver les données de la ligne. Existe-t-il un moyen simple de le faire en JSL ?
Vous pouvez créer une colonne de formule dans chaque table de données qui arrondit votre colonne d'horodatage aux 5 minutes les plus proches, puis utiliser ces colonnes pour la jointure.Dans JMP 14, si vous cliquez avec le bouton droit sur l'en-tête de votre colonne d'horodatage, puis sélectionnez Nouvelle colonne de formule->Transformer->Arrondir..., une boîte de dialogue s'affichera vous offrant la possibilité d'arrondir vers le haut, vers le bas ou vers le bas. à l'incrément de temps le plus proche souhaité.Si vous n'avez pas JMP 14, la formule pour arrondir à l'intervalle de 5 minutes le plus proche ressemblerait à ceci :
Rond( :Horodatage / 300 ) * 300
(Notez que 300 est le nombre de secondes dans 5 minutes).
La boîte de dialogue Tables->JMP Query Builder (ou Tables->Join) propose des options permettant de conserver les non-correspondances et de créer une colonne d'indicateur de correspondance.
J'espère que cela t'aides.
Il n'existe pas de plate-forme intégrée permettant d'effectuer une jointure avec une correspondance floue, car vous avez indiqué ce dont vous avez besoin.Cependant, JSL peut être utilisé pour obtenir ce dont vous avez besoin.
Voici un exemple approximatif d'une façon de scripter votre demande
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")
);