cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
ehchandlerjr
Level V

How to elegantly perform an update, but for a single row?

Hello - I'm trying to take a row from one table, and throw it into another table at a row the user specifies in an entry box. However, the update function doesn't seem to have the ability to specify rows, and so I'm left with taking an hour and typing out each of my 105 columns for both data tables as such: 

dt:{"ColA"}[rownumber] = dt1:{"ColA"}[1];
dt:{"ColB"}[rownumber] = dt1:{"ColB"}[1];
.
.
.
dt:{"ColDA"}[rownumber] = dt1:{"ColDA"}[1];

Which is fine, but I can imagine my coding friends squirming in their seats at that. Is there a more elegant way to do this? I've seen someone reference associative arrays, but I'm having trouble using them.

 

I assume the code above suffices, but if it matters, here is the original code, with the relevant line being five lines from before the closing parentheses start, and commented appropriately:

w = New Window( "Choose Row Number for XRD Run input", // opens a window with a title and this content...
    Border Box( top( 20 ), bottom( 20 ), Left( 20 ), Right( 20 ), // window dressing 
        V List Box( // V and H lists nest to organize the display boxes
            H Center Box( Text Box( "Choose Row Number for XRD Run input" ) ), // a second title, centered
            Spacer Box( size( 1, 30 ) ), // a little vertical space
            H Center Box( rowtemp=Number Edit Box( ) ), // data entry
            Spacer Box( size( 1, 10 ) ), // a little vertical space
            H Center Box( // center the button
                Button Box( "Import Data", // this script runs when the button is pressed...
					rownumber = rowtemp << Get;
                    // Run XML Import
                    Include( "jmpprj://contents/Import XRD XML.jsl");
                    // Reference Data Tables
                    dt = Data Table( "Experimental Info" );
                    dt1 = Data Table( "XMLTempTable" );
                    // Move to Experimental info table
                    dt:{"xsi:Schema Location 1"}[rownumber] = dt1:{"xsi:Schema Location 1"}[1]; //THIS ONE
                    // Close XMLTempTable
                    close(dt1);
                    // optionally, close the dialog. Or, you might want to run it again...
                    w << closeWindow; // just the dialog, not the report
                )
            )
        )
    )
); 

 

Edward Hamer Chandler, Jr.
2 REPLIES 2
txnelson
Super User

Re: How to elegantly perform an update, but for a single row?

Here is one way to do a single row update.  It takes a specified row from one data table, and updates it to a specified row in another data table.

names default to here(1);
dt=
// Open Data Table: Big Class.jmp
// → Data Table( "Big Class" )
Open( "$SAMPLE_DATA/Big Class.jmp" );

// Create a random data table with 5 rows
// Subset data table
// → Data Table( "Subset of Big Class" )
dt2 = dt << Subset( Sample Size( 5 ), Selected columns only( 0 ), output table("Selection") );

// Give new names to the subsetted table
dt2:name[1] = "PAT"; 
dt2:name[2] = "BRIT";
dt2:name[3] = "TERRY";
dt2:name[4] = "KRIS";
dt2:name[5] = "JEN";
wait(10);

// Below is the code that does the 1 row update

// Row in data table Big Class to be updated
outRow = 12;

// Row in data table Selection to get data from
inRow = 4;

// The Update process
// Create a row column in data table Big Class
dt << new column( "Row", formula(row()));

// Subset the inRow to a new table
dt2 << select where(row()== inRow);

dtTemp = dt2 << subset(selected rows(1), selected columns(0), invisible);

// Clear selected row in data table Selection
dt2 << clear select;

// Create a new column in the temp data table
dtTemp << new column("Row", set each value(outRow));

// Update data table Big Class
dt << Update(
	With( dtTemp ),
	Match Columns( :Row = :Row )
);

//  Delete the temp data table
close( dtTemp, nosave );

// Delete the Row Column
dt << delete columns( :Row );
Jim
hogi
Level XI

Re: How to elegantly perform an update, but for a single row?

If you have unique identifiers in both tables, like name and age, you could use them as match conditions.

 

In addition, you can use a virtual transform column row selection to provide an additional match condition to select the rows to update:

 

Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

New Namespace(
	"selection"
);

selection:ChangeRows = [5, 2, 7];

updateTable = dt << Subset( All rows, Selected columns only( 0 ) );
:weight << set each value( 1000 );

dt << Update(
	With( updateTable ),
	Match Columns(
		:name = :name,
		:age = :age,
		transform column( "row selection", Formula( If( N Items( Loc( selection:ChangeRows, Row() ) ), 1, . ) ) ) =
		transform column( "row selection", Formula( 1 ) )
	),
	Add Columns from Update Table( None ),
	Replace Columns in Main Table( :weight )
);