C'est simple, decimalNumberBySubtracting
y decimalNumberByDividingBy
ne fonctionnent pas ... du tout. Il n'y a pas d'erreur, juste des résultats erronés. J'ai vraiment besoin de résoudre ce problème, mais je ne reçois aucune erreur et je ne vois pas d'autre moyen de faire le calcul ! J'obtiens des chiffres comme :
257849691392950000000000000000000000000000000000000000000000000000000000000000000
Où ils devraient être évalués :
-0.581
Voici la longue histoire. J'essaie d'effectuer un simple calcul de Z-Score sur un ensemble de données. A Zscore
est défini comme suit (X - Average)/(stdDev)
. C'est assez simple. Mes données d'essai comprennent 5 plaques contenant chacune 96 échantillons. Ce code identifie chaque plaque individuelle, génère la moyenne et la stdev pour chaque plaque, puis pour chaque échantillon dans CETTE plaque, effectue le calcul ci-dessus.
//identify unique plates
NSSet * uniqueValues = [NSSet setWithArray:[items valueForKey:@"plate"]];
id i;
for (i in uniqueValues) {
//Lots of NSExpression and Predicate stuff I pulled out cause its working fine
NSExpression *plateMeanExpression = [NSExpression expressionForFunction:@"average:"
arguments:plateArgumentArray];
NSExpression *plateStdDevExpression = [NSExpression expressionForFunction:@"stddev:"
arguments:plateArgumentArray];
// generate Z Score and StDev:
NSDecimalNumber *zscoreMean = [plateMeanExpression expressionValueWithObject:nil
context:nil];
NSDecimalNumber *zscoreStdDev = [plateStdDevExpression expressionValueWithObject:nil
context:nil];
//iterate through samples in each plate and perform calculation, update CoreData
for (ScreenVariables *zValue in eachPlateArray) {
NSDecimalNumber *deltaTemp = [zValue valueForKey:@"delta"];
NSDecimalNumber *numerator = [deltaTemp decimalNumberBySubtracting:zscoreMean];
NSDecimalNumber *zScoreValue = [numerator decimalNumberByDividingBy:zscoreStdDev];
[zValue setZScore:zScoreValue];
Le problème est que lorsque j'exécute ce calcul, je devrais obtenir un nombre compris entre ~(-6,6) et 99 % des valeurs comprises entre -3 et 3. Voici un des points de données renvoyés :
257849691392950000000000000000000000000000000000000000000000000000000000000000000
Bon, d'accord, j'ai fait un peu de dépannage en insérant les variables deltaTemp
, numerator
, zscoreMean
, zscoreStdDev
dans mon NSTableView. L'idée était de voir à quoi XCode évaluait ces variables et de corriger celle qui posait problème. Je l'ai fait en utilisant ce code :
ScreenVariables *addData = [NSEntityDescription insertNewObjectForEntityForName:@"ScreenVariables"
inManagedObjectContext:self.managedObjectContext];
[addData setValue:deltaTemp forKey:@"someAvailableKey-1"];
[addData setValue:numerator forKey:@"someAvailableKey-2"];
[addData setValue:zscorePlateMean forKey:@"someAvailableKey-3"];
[addData setValue:zscoreStdDev forKey:@"someAvailableKey-4"];
J'ai des valeurs pour mes variables :
deltaTemp = -919
zscoreMean = -141
numerator = -919 // should be -778.58 = -919 -(-141)
zscoreStdDev = 1337.635067946411
Cela donne un score Z de -0.581...
C'est un ZScore parfaitement valide ... donc le problème est dans la :
[deltaTemp decimalNumberBySubtracting:zscoreMean];
[numerator decimalNumberByDividingBy:zscoreStdDev];
Le numérateur de la variable n'est pas évalué correctement et la valeur du zscore non plus. Dans mon modèle de données CoreData, le type d'entrée de chaque variable numérique est SPECIFIQUEMENT défini comme NSDecimalNumber. Je suppose donc que l'encodage des nombres est correct, car ils sont insérés individuellement sans problème...