Jarmo's code is spectacular. I enjoy seeing how he approaches and solves problems. But, for most of my life, I have been considered by my collogues, friends, spouse and children as being strange in thought. On good days, I am referred to as a "Nerd".
So given my status in life, I have found out that most people do not think the way I do.
@PruningTheSpark states
"I think this must need to be some sort of script as I cannot think of a formula that will work. I have no experience creating scripts so any help would be appreciated!!".
I believe that a majority of JMP users fall close to PruningTheSpark's position. PruningTheSpark may not think there is a non scripting solution to the problem, but JMP's interactive capabilities to manipulate one's data are really powerful. So below I have put together the interactive steps it takes to solve PruningTheSparks issue.
Starting with the sample data table that was provided, I did modify it slightly. Given the results from Jamo's script, it shows that none of the rows have more than one valid code. Given that more than one code is a potential, I added in code on row 2 that would show up for row 2 to have multiple codes.
The first task is to find all of the codes that fall within the Start Date and Stop Date. Since there are 6 different code columns, the easiest way to do this all at once is to stack the data .
Tables=>Stack
It is a Multiple series stack, staking the date and the code columns
Now I can get rid of all codes that have missing values since they will not figure into the results. So I selected one cell that has a missing value in the Data 2 column which contains all of the codes and then right click and choose Select Mating Cells
Which selects all of the rows that have missing values for column Data 2.
Right click in the RowState column and select Delete Rows
and you are left with only the rows that have codes
Now I need to determine which of these codes fall within the Start Date and the Stop Date. For this I am just going to create a new column, which I will call "in between" which has a formula of
which has a 1 for rows where the column Data (it contains the Date from the original table) has a 1 for being in the range and a 0 for being outside of the range
Using the same technique as when deleting the codes with a missing value, the rows with zeros can be selected and deleted
To clean up the table, some of the no longer needed columns can be deleted
Now the task is to get the codes back into single rows. To do this, a simple Split can be done
Tables=>Split
Now to combine the code columns into one column, a Column Utility called Combine Columns can be used. Just select the columns that are to be combined and then
Cols=>Utility=>Combine Columns
Which pops up an input box to fill in the name of the new column, and what delimiter to place between items, in this case, a ","
this results in the table having a new column
Clean up on the table by deleting the no longer needed columns gives
Now all that has to be done, is to move the results back into the original data table. To do this, the Update platform will do the trick. Click on the original table and
Tables=>Update
Fill in the table to get the update from, and select to match record_id of the original table with record_id from the Split table and click on OK and the original table will contain are solution
No script was used, only 2 simple formula columns were required.
Now, as one goes through these steps, JMP places in the log, the JSL required to create the interactive steps that were run. So one can simply copy those pieces of JSL into a script, and at the end have a script that when run will great the solution in the blink of an eye.
names default to here(1);
dt = data table( "Example Table" );
// Stack data table
// → Data Table( "Stacked" )
dtStacked = Data Table( "example table" ) << Stack(
columns(
:date_1, :code 1, :date_2, :code 2, :date_3, :code 3, :date_4, :code 4,
:date_5, :code 5, :date_6, :code 6
),
Number of Series( 2 ),
Output Table( "Stacked" )
);
wait(0);
// Delete selected rows
Data Table( "Stacked" ) << Select Where( Is Missing( :Data 2 ) ) << Delete Rows;
// Delete columns
Data Table( "Stacked" ) << Delete Columns( :Label, :Label 2 );
// New column: is between
Data Table( "Stacked" ) << New Column( "is between",
Numeric,
"Continuous",
Format( "Best", 12 )
);
// Change column formula: is between
Data Table( "Stacked" ):is between << Set Formula(
:Data >= :Start date & :Data <= :Stop date
);
// Delete selected rows
Data Table( "Stacked" ) << Select Where( :is between == 0 ) << delete rows;
// Delete column: is between
Data Table( "Stacked" ) << Delete Columns( :is between );
// Delete columns
Data Table( "Stacked" ) << Delete Columns( :Stop date, :Start date, :Data );
// Split data table
// → Data Table( "Split" )
Data Table( "Stacked" ) << Split(
Split By( :Data 2 ),
Split( :Data 2 ),
Group( :record_id ),
Output Table( "Split" ),
Sort by Column Property
);
// Combine columns
Data Table( "Split" ) << Combine Columns(
columns( :"1"n, :"2"n, :"3"n ),
Column Name( "Result" ),
Delimiter( "," )
);
// Delete columns
Data Table( "Split" ) << Delete Columns( :"1"n, :"2"n, :"3"n );
// Update data table
Data Table( "example table" ) << Update(
With( Data Table( "Split" ) ),
Match Columns( :record_id = :record_id )
);
One can also open a new workflow, turn on the recorder and step through the steps and you will end up with a workflow that can be used in the future to create the solution.
Jim