cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • Instantly extract effect sizes, F-ratios, and FDR-adjusted p-values from your models with the Calculate Effects Sizes extension, available now in the JMP Marketplace!
  • New to JMP? Join us Sept. 23-24 for the Early User Edition of Discovery Summit, tailor-made for new users. Register now for free!
  • Your voice matters! Tell us how you prefer to receive JMP updates, so we can tailor our communication to your needs. Take short survey.

Discussions

Solve problems, and share tips and tricks with other JMP users.
Choose Language Hide Translation Bar
learning_JSL
Level IV

I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

Hi - I have a table with columns that are made up of lab results (numeric values) that were entered as a text string.  They are text string because some have a "<" in front of the numeric value.  I need to be able to perform numeric calculations on the values so I am trying to remove the "<" symbol and place it in a new column that is named "ORIGCOLNAME_QUALIFIER" (where ORIGCOLNAME is the name of the column from which the "<" symbols were removed).  

Unfortunately, the below code is not working.

Names Default To Here( 1 );
dt = Current Data Table();

compList = {};
For( i = 1, i <= N Cols( dt ), i++,
colName = Column( dt, i ) << get name;
);

// Create the columns
For Each( {comp, i}, compList,
Eval(
Parse(
"dt << New Column( \!"" || compList[i] || "_QUALIFIER" ||
"\!",
character, nominal,
formula(
x=.; 

if (comp << contains ("<"), x = <);

 

I get the following message:  

learning_JSL_0-1694613341772.png

Any input would be most appreciated.

1 ACCEPTED SOLUTION

Accepted Solutions
txnelson
Super User

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

First, when posting JSL to a Community Discussion page, please use the JSL icon at the top of the page, so the code properly shows up ion the page.

 

Below is a script that checks for < and for any Post Script values such as "J" or "UJ" etc, and moves the values to a new Qualifier column.  It then converts the column from a character column to a numeric column

txnelson_0-1694631981313.png

Names Default To Here( 1 );
dt = Current Data Table();

colNames = dt << get column names( string, character );

For Each( {col, i}, colNames,
	GTFound = "NO";
	postScriptFound = "NO";
	
	// Find rows that have < in them
	theRows = dt << get rows where( Contains( As Column( dt, col ), "<" ) );
	// If < is found then 
	//      1. Create a new column to hold the < in
	//      2. Loop through the rows with < and
	//         1. Add < to the appropriate row in the new Qualifier column
	//         2. Delete the < from the current column
	If( N Rows( theRows ) > 0,
		GTFound = "YES";
		dt << add Multiple Columns( col, 1, Character );
		Column( dt, N Cols( dt ) ) << set name( col || "_QUALIFIER" );
		dt << move selected column( after( As Column( col ) ) );
		For Each( {fixRow, k}, theRows,
			As Column( dt, col || "_QUALIFIER" )[fixRow] = "<";
			As Column( dt, col )[fixRow] = Substr( Column( col )[fixRow], 2 );
		);
	);
	
	// Find if there are any post script values on any of the rows
	theRows = dt << get rows where( Word( 2, As Column( dt, col ), " " ) != "" );
	
	// If found, then if a new column has not already been add, add the new Qualifer column
	If( N Rows( theRows ) > 0,
		postScriptFound = "YES";
		If( GTFound == "NO",
			dt << add Multiple Columns( col, 1, Character );
			Column( dt, N Cols( dt ) ) << set name( col || "_QUALIFIER" );
			dt << move selected column( after( As Column( col ) ) );
		);

		// Loop through the rows with post scripts and
		//     1. Add the post scripts to the Qualifer column
		//     2. Delete the post scripts from the current column
		For Each( {fixRow, k}, theRows,
			As Column( dt, col || "_QUALIFIER" )[fixRow] = Trim(
				As Column( dt, col || "_QUALIFIER" )[fixRow] || " " || Word( 2, As Column( dt, col )[fixRow], " " )
			);
			As Column( dt, col )[fixRow] = Word( 1, As Column( dt, col )[fixRow], " " );
		);
	);
	
	// If eiter < or Post Scripts were found, convert the column to numeric, continuous
	If( GTFound == "YES" | postScriptFound == "YES",
		Column( dt, col ) << data type( numeric ) << modeling type( continuous )
	);
);

 

Jim

View solution in original post

9 REPLIES 9
learning_JSL
Level IV

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

Table attached, just in case.

jthi
Super User

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

This might give some ideas on what you could do

Names Default To Here(1);

dt = New Table("Untitled",
	Add Rows(2),
	Compress File When Saved(1),
	New Column("Column 1", Character, "Nominal", Set Values({"<1", "<3"})),
	New Column("Column 2", Character, "Nominal", Set Values({"<2", "<4"}))
);


col_names = dt << Get Column Names("String");

For Each({col_name}, col_names,
	dt << New Column(col_name ||"_Q", Numeric, Continuous, << Set Each Value(
		Num(Substitute(AsColumn(dt, col_name), "<", ""));
	));
);

Search Scripting Index and Scripting Guide for Substitute() to learn more about how it can be used

-Jarmo
learning_JSL
Level IV

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

Thanks jthi - The first part of your code creates a new 2-row table with pre-named columns.  

Names Default To Here( 1 );
dt = New Table( "Untitled",
	Add Rows( 2 ),
	Compress File When Saved( 1 ),
	New Column( "Column 1", Character, "Nominal", Set Values( {"<1", "<3"} ) ),
	New Column( "Column 2", Character, "Nominal", Set Values( {"<2", "<4"} ) )
);

However, I am trying to keep my column names intact while adding a new column with name corresponding to each of my existing columns but with "_qualifier" on the end.    (Ex:  say my existing columns are chloride (character), sulfate (sulfate), ..., the new columns would be chloride (numeric), sulfate (numeric), chloride_qualifier (character), sulfate_qualifier (character), etc. 

jthi
Super User

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

Just substitute that part with a reference to your table. You might also want to cleanup the column selection if you know which should be used (instead of just using << get column names("String") to get all columns).

-Jarmo
learning_JSL
Level IV

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

Unfortunately I'm not following how that code applies to my original question.  I probably was not clear in my original post or am missing something (I'm a jsl novice).  In any case, I'll keep trying and may need to re-frame my question.  (By the way, I have a very large number of columns in play, and all but the datetime column need this treatment - far too many to define by hand.)  Thanks again. 

txnelson
Super User

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

First, when posting JSL to a Community Discussion page, please use the JSL icon at the top of the page, so the code properly shows up ion the page.

 

Below is a script that checks for < and for any Post Script values such as "J" or "UJ" etc, and moves the values to a new Qualifier column.  It then converts the column from a character column to a numeric column

txnelson_0-1694631981313.png

Names Default To Here( 1 );
dt = Current Data Table();

colNames = dt << get column names( string, character );

For Each( {col, i}, colNames,
	GTFound = "NO";
	postScriptFound = "NO";
	
	// Find rows that have < in them
	theRows = dt << get rows where( Contains( As Column( dt, col ), "<" ) );
	// If < is found then 
	//      1. Create a new column to hold the < in
	//      2. Loop through the rows with < and
	//         1. Add < to the appropriate row in the new Qualifier column
	//         2. Delete the < from the current column
	If( N Rows( theRows ) > 0,
		GTFound = "YES";
		dt << add Multiple Columns( col, 1, Character );
		Column( dt, N Cols( dt ) ) << set name( col || "_QUALIFIER" );
		dt << move selected column( after( As Column( col ) ) );
		For Each( {fixRow, k}, theRows,
			As Column( dt, col || "_QUALIFIER" )[fixRow] = "<";
			As Column( dt, col )[fixRow] = Substr( Column( col )[fixRow], 2 );
		);
	);
	
	// Find if there are any post script values on any of the rows
	theRows = dt << get rows where( Word( 2, As Column( dt, col ), " " ) != "" );
	
	// If found, then if a new column has not already been add, add the new Qualifer column
	If( N Rows( theRows ) > 0,
		postScriptFound = "YES";
		If( GTFound == "NO",
			dt << add Multiple Columns( col, 1, Character );
			Column( dt, N Cols( dt ) ) << set name( col || "_QUALIFIER" );
			dt << move selected column( after( As Column( col ) ) );
		);

		// Loop through the rows with post scripts and
		//     1. Add the post scripts to the Qualifer column
		//     2. Delete the post scripts from the current column
		For Each( {fixRow, k}, theRows,
			As Column( dt, col || "_QUALIFIER" )[fixRow] = Trim(
				As Column( dt, col || "_QUALIFIER" )[fixRow] || " " || Word( 2, As Column( dt, col )[fixRow], " " )
			);
			As Column( dt, col )[fixRow] = Word( 1, As Column( dt, col )[fixRow], " " );
		);
	);
	
	// If eiter < or Post Scripts were found, convert the column to numeric, continuous
	If( GTFound == "YES" | postScriptFound == "YES",
		Column( dt, col ) << data type( numeric ) << modeling type( continuous )
	);
);

 

Jim
learning_JSL
Level IV

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

That worked perfectly.  And the comment lines are most helpful as they will help me understand each step in the process.  This augments what I can find in the help documentation as I learn how to actually apply these jsl fundamentals to my dataset.  Thank you very much.

gzmorgan0
Super User (Alumni)

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

I might not understand your need, and there are likely more efficient ways to do this, especially if your data has many rows, but here is a brute force method if this table looks like the result you want.

gzmorgan0_0-1694638162959.png

 

Names Default To Here(1);
id_colnames = {"well", "Sample Date"};

dt = Current Data Table();
nr =nrow(dt);

col_names = dt << Get Column Names("String");

For Each({col_name}, col_names,
   If( !Contains(id_colnames, col_name),
   	  dt << New Column(col_name||"_Q", Character, << Set Each Value(
   	  	If(Contains(AsColumn(dt,col_name), "<"), "<",""))
   	  );
   	  
      curr_col = column(dt,col_name);
      For(i=1, i<=nr, i++,
         curr_col[i]= Substitute( word(1, curr_col[i]) ,"<","");
       );
      curr_col << Set Data Type(Numeric) << Set Modeling Type ("Continuous");
   	); // end If()
 );  //end For Each()
 

 

learning_JSL
Level IV

Re: I am trying to reset columns with a character ("<") to numeric and retain the "<" in another column

Thanks GZMorngan0!    Sorry I'm slow responding.  I just checked back on the thread. 

I appreciate seeing another technique. 

Recommended Articles