Is there a way to reorder columns in a ResultsTable?

Hello,

does anyone know if it’s possible to reorder columns in an ImageJ ResultsTable? (I don’t mean sorting).

I use the particle analyzer for region analysis and want to prepend two descriptive columns (image name and region label). But rt.setLabel only allows me to preprend one label column. And I can only fill in the region label column after I ran the particle analyzer.

This is a minimal example of how it currently looks: Area is the result of Particle Analyzer, and RegionLabel is what I add later but would want to appear it in this order: Label, RegionLabel, Area.
resultstable

Jython code to reproduce this:

from ij.plugin.filter import ParticleAnalyzer as PA 
from ij import IJ
from ij.measure import ResultsTable

# create a binary image
IJ.run("Blobs (25K)");
mask=IJ.getImage();
IJ.setAutoThreshold(mask, "Default");
IJ.run(mask, "Convert to Mask", "");

rt=ResultsTable()
last_used_row=rt.getCounter()

# PA settings
IJ.run(None, "Set Measurements...", "mean redirect=None decimal=3")
options =  PA.CLEAR_WORKSHEET
measurements=PA.AREA

#  particle analyzer
p = PA(options, measurements, rt, 0, 100000000000)
p.analyze(mask)

# now add 2 descriptive the labels
# add column with image file name
for rtidx in range (last_used_row,rt.getCounter()): # zero based
	rt.setLabel(mask.getTitle(),rtidx)

# add label ids of rois
for counter,rtidx in enumerate(range(last_used_row,rt.getCounter())): # zero based
	rt.setValue("RegionLabel",rtidx,counter+1)

rt.show("Results")

PS: I know that one can display the row numbers but that is not what I’m looking for since I merge results of many images into one table.

Does the following demo macro help?

a = newArray(1,2,0,0,5,0,7,8,0,10,11,12,0,14,0,16,0);
b = newArray(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17);
c = newArray("z","y","x","w","v","u","t","s","r","q","p","o","n","m","l","k","j");
Table.create("Test");
Table.setColumn("Area", a);
aa=Table.getColumn("Area");
Table.create("Test Rearranged Columns");
Table.setColumn("Label", c);
Table.setColumn("RegionLabel", b);
Table.setColumn("Area", aa);

This can hardly be changed.

Hi ,
thanks for the tips! I fear this may not work in jython though. I had a quick try but somehow the results table does not get filled when I use the corresponding get & set methods, e.g. setColumn(java.lang.String column, Variable[] array) (API link). I also don’t understand the Variable[] type.

If it is possible in the macro language, it is possible in Java and therefore also in Jython.

Hi @noreenw ,

some time ago, I programmed this function which sorts columns in a table alphabetically by making a new table:
clijx-weka/TrainWekaFromTable.java at 866475225eb84744f209103c3d3ff033ce30e94e · clij/clijx-weka · GitHub

Feel free to cherry pick!

Cheers,
Robert

1 Like

Thanks for the link @haesleinhuepf !
yes I think I’ll do something in this spirit now, first sorting the column headers and then re-writing all elements.

1 Like

In case anyone runs into a similar issue, here is a solution that worked for me. It brings a column of choice to the front:
To run the example, a Results table must be open.

from ij.measure import ResultsTable

def reorderTable(rt, specialtitle):
	"""Creates a new results table where the column 'specialtitle' is moved to the front to be 
	the first column (after Labels). Copies the labels column and all other columns.
	returns: rtordered: results table with columns: (Labels, specialtitle, [allothercolumns])
	"""
	nrows=rt.getCounter()

	rtordered=ResultsTable()
	
	# fill the special column first
	specialidx=rt.getColumnIndex(specialtitle)
	colspecial=rt.getColumn(specialidx)
	for idx in range(nrows):
		rtordered.setValue(specialtitle,idx,colspecial[idx])

	# fill all other columns
	coltitles=rt.getHeadings()
	for coltitle in coltitles:
		if (coltitle!=specialtitle) and (coltitle!="Label"):
			colidx=rt.getColumnIndex(coltitle)
			col=rt.getColumn(colidx)
			for idx in range(nrows):
				rtordered.setValue(coltitle,idx,col[idx])
			
	# add labels (to front)
	for idx in range(nrows):
		rtordered.setLabel(rt.getLabel(idx),idx)

	return rtordered


# reorder the results table
rt=ResultsTable.getResultsTable()
rtordered=reorderTable(rt, "Angle") # example: make 'Angle' first column
rtordered.show("Ordered")