cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
hcarr01
Level VI

Script

Bonjour à tous,
 
Je dispose d’une base de données dans laquelle j’aimerais créer une nouvelle colonne à partir d’une formule ou d’un script.
 
Voici un aperçu de la base de données :
 
hcarr01_1-1689685617209.png

 

- la colonne T représente des opérations à effectuer
- la colonne X_3 représente une particularité
- La colonne op représente des objets
 
Le but est de créer une colonne « bilan » dans laquelle on ajoute « ko » et le numéro correspondant à « op » lorsque la somme des défauts est différente de 0 d’une ligne à une autre pour un même « obj » (ici valeur égale à A).
 
Dernière particularité, la colonne bilan doit être remplie pour la numéro des opérations « 3061 ».
Il s’agit ici d’un aperçu de la base de données, la colonne obj vaut « A » mais dans la base de données cette colonne change de valeur.
 
Merci pour vos réponses !
1 ACCEPTED SOLUTION

Accepted Solutions
hcarr01
Level VI

Re: Script

J'ai rajouté cette partie cela fonctionne encore mieux :

 

Names Default To Here(1);

dt = current data table();
dt << New Column("BILAN", Character, Nominal);


Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];


somme_col = Filter Each( {col_name}, dt << Get Column Names( "String", Continuous ),
	Starts With( col_name, "SOMME" )
);



dt = current data table();
For Each({unique_objects}, unique_objects,
	object_rows = Loc(m_obs, unique_objects); // lignes pour chaque obj
	b = dt[object_rows, "OPE"]; // les différentes opé pour chaque obj
	show(b);
	input_loc = Loc(dt[object_rows, "T"], "3061"); // localiser 3061 pour chaque objet
	
	if( N items(input_loc) < 1,
		continue();
	,
	
		z = object_rows[input_loc]; // localiser les lignes OPE 3061 pour chaque obj
		value_OPE_3061 = :OPE[z]; // valeur de l'ope 3061 pour chaque obj
		
		liste={}; // transformer en liste pour supprimer les doublons
		for (i = 1, i <= NRows(value_OPE_3061), i++,
			for (j = 1, j <= NCols(value_OPE_3061), j++,
				InsertInto(liste, value_OPE_3061[i, j]);
			);
		);
		
		// supprimer les doublons
		if( N items(liste) <= 1, 
			a = liste;
		,
			a = Left(liste,1);
		);
		
		// repasser en matrice pour faire les comparaisons
		Mat_3061 = Matrix(a);
		show(Mat_3061);
		

		valid_ope_idx = Loc(b > Mat_3061 & dt[object_rows,somme_col] > 0) ;
		show(valid_ope_idx); 
		
	
		if( N items(valid_ope_idx) < 1,
			continue();
		,
			ops = dt[object_rows[valid_ope_idx], "op"];
			result_str = "ko - " || Concat Items(ops, " / ko - ");
			dt[object_rows[input_loc], "BILAN"] = Repeat({result_str}, N Items(input_loc));
		);

);
);

Effectivement vous avez raison @jthi, mais je parlais que pour une valeur 3061 d'un :obj il ne peut pas y avoir différentes valeurs de la variable :OPE (après dans un obj il peut y avoir 2 fois par exemple la valeur :T égale à 3061 mais la valeur :OPE sera la même).

 

Au final, en sortie, j'aimerais que l'affichage ne se répète pas lorsqu'il y a plusieurs fois la valeur :T égale à 3061 pour un même :obj.

 

Exemple : 

 

hcarr01_0-1690276418497.png

 

Avec un script comme celui-ci :

input_loc = Loc(dt[object_rows, "T"], "3061");// localiser 3061 pour chaque objet
	
	liste2={}; // transformer en liste pour supprimer les doublons
		for (i = 1, i <= NRows(input_loc), i++,
			for (j = 1, j <= NCols(input_loc), j++,
				InsertInto(liste2, input_loc[i, j]);
			);
		);
		
		// supprimer les doublons
		if( N items(liste2) <= 1, 
			c = liste2;
		,
			c = Left(liste2,1);
		);
		
		// repasser en matrice pour faire les comparaisons
		loc_3061 = Matrix(c);
		

Cela fonctionne correctement, je prends le premier indice correspondant à :T égale à 3061.

 

Mais comme sur la capture ci-dessus, j'aimerais pouvoir enlever les éléments en double sur la même ligne :

ko - 2203 / ko - 2203 --> ko - 2203

 

 

View solution in original post

27 REPLIES 27
jthi
Super User

Re: Script

Why isn't row 6 op 180 being added to last column? 0 does differ from 1.

 

(You should use more informative post titles than just one word)

-Jarmo
hcarr01
Level VI

Re: Script

Car la somme est égale à 0 pour la ligne 6. En fait, c'est plutôt quand la somme des défauts est différente de la valeur 0 alors on renseigne la valeur de "op" dans la colonne "bilan".

jthi
Super User

Re: Script

So is there any need to check if the values differ between two rows? Or are you just interested in rows which have :op other than 0?

-Jarmo
hcarr01
Level VI

Re: Script

je pense que nous pouvons nous intéresser seulement aux lignes où la valeur de :somme défaut est différente de 0. Car quand la valeur de :somme défaut vaut 0 alors on se renseigne rien dans la colonne bilan.

jthi
Super User

Re: Script

This script does both and works with the provided example. I strongly suggest you try to understand what it does and ask if there are some parts which you don't.

Names Default To Here(1);

dt = Open("$DOWNLOADS/AAA.jmp");
dt << New Column("bilan2", Character, Nominal);
dt << New Column("bilan3", Character, Nominal);


Summarize(dt, unique_objects = by(:obj));
m_obs = dt[0, "obj"];

/* comparing rows */
For Each({unique_object}, unique_objects,
	object_rows = Loc(m_obs, unique_object);
	values = dt[object_rows, "SOMME DEFAUT"];
	values1 = Remove(values, 1);
	values2 = Remove(values, N Items(values));
	differences = [0] |/ values1 - values2;
	
	ops = dt[object_rows[Loc(differences != 0)], "op"];
	
	result_str = "ko - " || Concat Items(ops, " / ko - ");
	
	input_loc = Loc(dt[object_rows, "T"], "3061");
	If(N Items(input_loc) < 0,
		continue();
	,
		dt[object_rows[input_loc], "bilan2"] = Repeat({result_str}, N Items(input_loc));
	);
 );
 
 
 /* zeros */
For Each({unique_object}, unique_objects,
	object_rows = Loc(m_obs, unique_object);
	values = dt[object_rows, "SOMME DEFAUT"];
	
	ops = dt[object_rows[Loc(values)], "op"];
	
	result_str = "ko - " || Concat Items(ops, " / ko - ");
	
	input_loc = Loc(dt[object_rows, "T"], "3061");
	If(N Items(input_loc) < 1,
		continue();
	,
		dt[object_rows[input_loc], "bilan3"] = Repeat({result_str}, N Items(input_loc));
	);
 );

jthi_0-1689687077723.png

 

Edit: Modified if statement If(N Items(input_loc)... from < 0 to < 1

Edit: Fixed line where values are being inputted to column to use object rows instead of rows from whole table

-Jarmo
hcarr01
Level VI

Re: Script

Merci pour votre réponse !
 
En comparant les deux méthodes, il me semble que la seconde est préférable pour mon cas de figure.
Je l’ai adapté à ma base de données, les colonnes ont les mêmes formats sur les deux bases de données et j’obtiens ce type d’erreur :

 

hcarr01_0-1689688581872.png

 

jthi
Super User

Re: Script

As the error message is in french I cannot understand it. It could be that the error is in the end telling you that you don't have bilan3 column. (It is saying that there is invalid subscript but that is caused by not having bilan3 column. This is because dt[input_loc, "bilan3"]  will return [](1, 0) if you don't have the column and then you try to set some values to it).

-Jarmo
hcarr01
Level VI

Re: Script

Cela provient du fait que la variable "input_loc" est vide. Donc pour l'affectation des nouvelles cellules dans la colonne "bilan3" c'est impossible.

jthi
Super User

Re: Script

Value "3061" (character, not number) is not being found from column "T". Also the check I have implemented to handle empty input_loc is incorrect, you should modify it to < 1 instead of < 0.

-Jarmo