Calculer la valeur médiane d'une colonne et dire si cette valeur est "OK" ou "ERREUR" si elle se situe dans une plage acceptable

Je voudrais calculer la valeur médiane d'une colonne particulière dans un file .txt, sortir cette valeur et aussi dire si cette valeur de sortie est ok. Je peux faire les étapes initiales et sortir la valeur médiane, mais il ne peut pas dire si la valeur de sortie est dans la plage acceptable.

Je reçois un message d'erreur de syntaxe avec le code suivant:

sort -nk9 filename | awk '{a[i++]=$9;} END {x=int((i+1)/2); y=((a[x-1] + a[x])/2); z=(a[x-1]); if ((y >= 0.5 && y <= 2) || (z >= 0.5 && z <=2)); {if (x < (i+1)/2) print "Median OR =", y "ALL OK"; else print "Median OR =", z "ALL OK"}; else print "ERROR - OR outside range 0.5 - 2.0"}' 

Je pense que c'est ce que tu veux

 awk '{sum+=$9;a[x++]=$9;b[$9]++}b[$9]>Mode{Mode=$9}END{print "Mean: " sum/x "\nMedian: "a[int((x-1)/2)]"\nMode: " Mode}' file 

Préparé plus propre

 awk ' { sum+=$9 a[x++]=$9 b[$9]++ } b[$9]>Mode{Mode=$9} END{ print "Mean: " sum/x print "Median: "a[int((x-1)/2)] print "Mode: " Mode }' file 

Aussi, je vais append une certaine logique pour les comparaisons, mais je ne sais pas réellement ce que vous essayez de comparer comme votre variable sont appelés simplement x, y, z et ne peuvent pas avoir les équations correctes

Je suis reconnaissant pour le code user78605 a fourni, car il m'a guidé dans la direction de la façon de find la médiane dans mes requêtes. Le code ci-dessus, cependant, néglige certaines conditions qui sont nécessaires pour calculer correctement la médiane.

Problèmes:

  1. Les lignes de fuite vierges (si elles existent dans le file) ne doivent pas être comptées car leur comptage affecte la taille des données et donc la moyenne, la médiane, le mode ainsi que d'autres quantités statistics. La même chose devrait probablement être faite pour les lignes qui n'ont pas de valeurs numériques (id est: "abc" , "28b" , "h2f" , "" , et cetera).
  2. Médiane est la valeur moyenne de l'set de données d'origine, mais un set de données ordonnées. C'est-à-dire que datatables pour lesquelles la médiane doit être trouvée doivent être sortingées en premier.
  3. Si la quantité de valeurs dans un set de données ordonnées est égale, la moyenne des deux valeurs intermédiaires doit être prise.
  4. Le mode est une valeur qui a la plus haute fréquence. Il est possible que l'set de données ait plus d'un mode, auquel cas deux valeurs ou plus doivent être répertoriées en tant que mode.

Ce qui suit est mon expansion du code, count tenu des conditions mentionnées ci-dessus:

 awk -F',' ' {col=$1}{if((col ~ /^-?[0-9]*([.][0-9]+)?$/) && ($0!="")) { sum+=col; a[x++]=col; b[col]++ if(b[col]>hf){hf=b[col]} } } END{n = asort(a);idx=int((x+1)/2) print "Mean: " sum/x print "Median: " ((idx==(x+1)/2) ? a[idx] : (a[idx]+a[idx+1])/2) for (i in b){if(b[i]==hf){(k=="") ? (k=i):(k=k FS i)}{FS=","}} print "Mode: " k }' file 

EXPLICATION:

Solution pour la question # 1:

col=$1 #easier pour changer les colonnes si elles sont stockées dans une variable.
(col ~ /^-?[0-9]*([.][0-9]+)?$/) string ne doit contenir que des numbers, un point (séparateur décimal) ou un tiret (signe less) . [Seule la notation scientifique est ignorée.]
($0!="") # Toute la ligne ne doit pas être vide.

Sur les lignes éligibles, exécutez les opérations de boucle suivantes:

sum+=col # (court pour sum=sum+col ) Somme de toutes les valeurs.
a[x++]=col #Every est stockée dans un tableau.
b[col]++ #Les valeurs de col sont traitées comme des keys de substitution du tableau b . Par conséquent, il y a seulement autant d'éléments dans b que le nombre de valeurs uniques dans col . Cet iterator crée un tableau de fréquences. (Court pour b[col]=b[col]+1 .)
if(b[col]>hf){hf=b[col]} #Let hf signifie «la plus haute fréquence». Faites défiler toutes les fréquences et mettez à jour hf uniquement si des fréquences plus élevées sont trouvées. hf est initialement "" (rien).

Solution pour la question # 2:
Une fois les opérations de bouclage terminées:

Trier les valeurs stockées dans le tableau: n = asort(a)

Il est important de noter que les indices originaux du tableau a variaient de "0" à "x-1". En plus du sorting, la nouvelle gamme d'index va de "1" à "x". C'est pourquoi j'utilise int((x+1)/2) au lieu de
int((x-1)/2) comme index qui contient la médiane – ou le plus petit des deux nombres qui seront moyennés à une médiane.

Solution pour le problème # 3:

((idx == (x+1)/2) ? a[idx] : (a[idx]+a[idx+1])/2)
C'est une notation abrégée pour une construction if-else:
Si int((x+1)/2) est égal à (x+1)/2 alors le nombre de valeurs est impair et la médiane sera a[idx] . Si ce n'est pas le cas, int() arrondira (x+1)/2 à l'entier le plus proche signifiant que le nombre de valeurs est pair. Dans ce cas, la moyenne d' a[idx] et d' a[idx]+1 sera la médiane.

Solution pour le problème # 4:

for (i in b) {if(b[i]==hf){(k=="") ? (k=i):(k=k FS i)}{FS=","}}
Puisque hf est la valeur qui représente la fréquence la plus élevée dans l'set de données, si une valeur quelconque de b est égale à hf , sa key de substitution est le mode ou au less l'un des modes.
Ce code concatène toutes les keys de substitution, i , qui correspondent au critère et les stocke dans une variable, k , qui peut être imprimée sur une ligne avec le titre "Mode".

Autres ajustements:

-F doit être ajusté en fonction du caractère utilisé comme séparateur de colonne dans le file.

Si le file a des en-têtes sur la première ligne, ajoutez NR > 1 devant {col=$1} .

FS été utilisé pour concaténer deux variables set. L'utilisation de FS est particulièrement utile lorsque l'on choisit de ne pas utiliser le séparateur. C'est-à-dire, FS="" .

Les données

Les données suivantes ont été utilisées pour l'expérimentation afin de créer le script:

 10 20 10 20.5 50 30 40 50 10 30 20.5 -h h 4.35 -537 0 -0 30 d . 

RÉSULTATS:

 Mean: -13.2281 Median: 20.25 Mode: 10,30