Vous êtes sur la page 1sur 50

Traduit de Anglais vers Français - www.onlinedoctranslator.

com

Chapitre 11. Types de données Gretl 89

print "x : aucun objet de ce type"

printf "x est de type %s\n", typestr(type) endif

Outre l'ajout, l'accès, le remplacement et la suppression d'éléments individuels, les autres opérations prises en charge pour les
ensembles sont l'union, l'impression et la suppression. En ce qui concerne l'union, si les faisceauxb1etb2sont définis, vous
pouvez dire

faisceau b3 = b1 + b2

pour créer un nouveau paquet qui est l'union des deux autres. L'algorithme est : créer un nouveau bundle qui est
une copie deb1,puis ajoutez tous les éléments deb2dont les clés ne sont pas déjà présentes dans le nouveau
bundle. (Cela signifie que l'union de bundles n'est pas commutative si les bundles ont une ou plusieurs chaînes de
clés en commun.)
Sibest un paquet et vous ditesimprimer b,vous obtenez une liste des clés du bundle avec les types des
objets correspondants, comme dans

? imprimer b
empaqueter b :
x (scalaire)
tapis (matrice)
à l'intérieur (paquet)

Notez que dans l'exemple ci-dessus, le bundlebimbrique un bundle nomméà l'intérieur.Si vous voulez voir ce qu'il y a à
l'intérieur des bundles imbriqués (avec une seule commande), vous pouvez ajouter le --arbreoption à la commande
d'impression.

Séries et listes en tant que membres du bundle

Il est possible d'ajouter à la fois des séries et des listes à un ensemble, comme dans

données ouvertes4-10
liste X = const CATHOL INCOME bundle
b
par = INSCRIRE
bX = X
eval par
eval bX

Cependant, il est important de garder à l'esprit les limitations suivantes.

• Une série, en tant que telle, est intrinsèquement membre d'un ensemble de données, et un ensemble peut « survivre » au
remplacement ou à la destruction de l'ensemble de données à partir duquel une série a été ajoutée. Il peut alors être
impossible (ou, même si possible, dénué de sens) d'extraire une série groupéeen série. Cependant il est toujours possible
de récupérer les valeurs de la série sous forme de matrice (vecteur colonne).

• Dans les commandes gretl qui appellent des arguments de série, vous ne pouvez pas donner une série groupée
sans d'abord l'extraire. Dans le petit exemple au-dessus de la sérieINSCRIREa été ajouté au lotbsous la cléy,mais
parn'est pas lui-même une série (membre d'un ensemble de données), c'est juste un tableau anonyme de valeurs.
Il ne peut donc pas être donné comme, disons, la variable dépendante dans un appel à la fonction de gretlols
commande.

• Une liste gretl est juste un tableau de numéros d'identification de séries dans un ensemble de données donné, une "macro" si vous préférez.
Ainsi, comme pour les séries, il n'y a aucune garantie qu'une liste groupée puisse être extraitesous forme de liste(bien qu'il puisse toujours
être extrait en tant que vecteur ligne).
Chapitre 11. Types de données Gretl 90

Les points soulevés ci-dessus sont illustrés dans la liste11.1. Dans le "cas 1", nous ouvrons un petit ensemble de données avec
seulement 14 observations transversales et mettons une série dans un ensemble. Nous ouvrons ensuite un ensemble de
données de séries chronologiques avec 64 observations, tout en préservant le bundle, et extrayons la série groupée. Cet exemple
est juridique, puisque la série stockée ne dépasse pas la longueur du nouvel ensemble de données (elle est écrite dans les 14
premières observations), mais ce n'est probablement pas significatif. C'est à l'utilisateur de décider si de telles opérations ont un
sens.

Dans le "cas 2", une séquence similaire d'instructions conduit à une erreur (piégée parattraper)car cette fois, la série stockée ne
rentrera pas dans le nouveau jeu de données. Nous pouvons néanmoins saisir les données sous forme de vecteur.

Dans « Cas 3 », nous mettons une liste de trois séries dans un paquet. Cela ne place aucune valeur de données réelle dans le groupe, juste
les numéros d'identification de la série spécifiée, qui se trouvent être 4, 5 et 6. Nous passons ensuite à un ensemble de données qui ne
contient que 4 séries, de sorte que la liste ne peut pas être extraite comme tel (les ID 5 et 6 sont hors limites). Encore une fois, cependant,
nous pouvons récupérer les numéros d'identification sous forme de matrice si nous le voulons.

Dans certains cas, mettre une liste gretl en tant que telle dans un bundle peut être approprié, mais dans d'autres, il vaut mieux
ajouter lecontenude la liste, sous forme matricielle, comme dans

données ouvertes4-10
liste X = const CATHOL INCOME bundle
b
matrice bX = {X}

Dans ce cas, nous ajoutons une matrice à trois colonnes et autant de lignes qu'il y en a dans l'ensemble de données ; nous avons
les données réelles, pas seulement une référence aux données qui pourraient « mal tourner ». Voir chapitre17pour en savoir plus
à ce sujet.

A quoi servent les bundles ?


Il est peu probable que les bundles soient intéressants dans le contexte de scripts gretl autonomes, mais ils
peuvent être très utiles dans le contexte de packages de fonctions complexes où une grande quantité
d'informations doit être transmise entre les fonctions du composant (voirCottrell et Lucchetti,2016). Au lieu
d'utiliser une longue liste d'arguments individuels, la fonctionUNpeut regrouper les données requises et les
transmettre aux fonctionsBetC, où les informations pertinentes peuvent être extraites via une clé mnémonique.
Dans ce contexte, les bundles doivent être passés sous forme de "pointeur" (voir chapitre14) comme illustré dans
l'exemple trivial suivant, où un bundle est créé à un niveau puis rempli par une fonction distincte.

# modification de bundle (pointeur) par fonction utilisateur

fonction void fill_out_bundle (bundle *b)


b.mat = Je(3)
b.str = "fou"
bx = 32
fonction de fin

bundle mon_bundle
fill_out_bundle(&my_bundle)

Le type de faisceau peut également être utilisé à son avantage car levaleur de retourà partir d'une fonction packagée,
dans les cas où un créateur de package souhaite donner à l'utilisateur la possibilité d'accéder à divers résultats. Dans
l'interface graphique gretl, les packages de fonctions qui renvoient un bundle sont traités de manière spéciale : la fenêtre
de sortie qui affiche les résultats imprimés acquiert un menu affichant les éléments groupés (leurs noms et types), à
partir duquel l'utilisateur peut enregistrer les éléments qui l'intéressent. Par exemple, un package de fonctions qui
estime un modèle peut renvoyer un ensemble contenant un vecteur d'estimations de paramètres, une série résiduelle et
une matrice de covariance pour les estimations de paramètres, entre autres possibilités.

En tant que raffinement pour prendre en charge l'utilisation de bundles comme type de retour de fonction, lesetnoteLa fonction
peut être utilisée pour ajouter une brève note explicative à un article groupé - ces notes seront alors affichées dans le
Chapitre 11. Types de données Gretl 91

Liste 11.1 :Séries et listes en lots[Télécharger▼]

# Cas 1 : stocker et récupérer des séries, OK ? données


ouvertes4-1
paquet b
série bx = sqft open data9-7 --
preserve series x = bx

imprimer x --byobs

# Cas 2 : stocker et récupérer des séries : donne une erreur,


# mais les données peuvent être récupérées sous forme matricielle
open data9-7
paquet b
série bx = QNC open data4-1 --
preserve
catch series x = bx # faux, ne rentre pas ! si $erreur

matrice mx = bx
imprimer MX
autre
imprimer X
fin si

# Cas 3 : stocker et récupérer la liste : donne une erreur,


# mais les numéros d'identification de la liste peuvent être récupérés
# en tant que vecteur
ligne open data9-7
liste L = PRIME UNEMP STOCK liasse
b
liste bL = L
open data4-1 --preserve catch
list L = bL
si $erreur
matrice mL = bL
print mL # imprime "4 5 6" endif
Chapitre 11. Types de données Gretl 92

menu de l'interface graphique. Cette fonction prend trois arguments : le nom d'un ensemble, une chaîne de clé et la note. Par
exemple

setnote(b, "vcv", "matrice de covariance")

Après cela, l'objet sous la cléVCVen lotbsera affiché comme "matrice de covariance" dans un menu GUI.

11.8 Tableaux
Le type de tableau gretl est destiné à l'utilisation de scripts. Les tableaux n'ont pas de représentation graphique et il est peu probable
qu'ils en acquièrent une.2

Un tableau gretl est, comme on peut s'y attendre, un conteneur qui peut contenir zéro ou plusieurs objets d'un certain
type, indexés par des entiers consécutifs commençant à 1. Il est unidimensionnel. Ce type est implémenté par un back-
end assez "générique". Les types d'objets pouvant être placés dans des tableaux sont les chaînes, les matrices, les listes,
les bundles et les tableaux.3

Parmi les types "primaires" de gretl, ni les scalaires ni les séries ne sont pris en charge par le mécanisme de tableau. Il serait peu
utile de supporter des tableaux de scalaires en tant que tels puisque le type matrice joue déjà ce rôle, et de manière plus flexible.
Quant aux séries, elles ont un statut spécial en tant qu'éléments d'un ensemble de données (qui est déjà en quelque sorte un
"tableau de séries") et en plus nous avons le type liste qui fonctionne déjà comme une sorte de tableau pour les sous-ensembles
de la série dans un ensemble de données.

Création d'un tableau

Un tableau peut être créé de quatre manières : déclaration simple, affectation à partir denul, ou en utilisant
l'une des fonctionsdéployer()oudefarray().Dans chaque cas, l'un des mots types spécifiques chaînes,
matrices, listes, bundlesoutableauxdoit être utilisé. Voici quelques exemples:

# déclarer un tableau vide de chaînes strings S

# faire un tableau vide de matrices matrices


M = null
# créer un tableau avec de la place pour quatre bundles
bundles B = array(4)
# créer un tableau avec trois chaînes spécifiées strings P =
defarray("foo", "bar", "baz")

Le formulaire « simple déclaration » et le « =nul"form ont le même effet de créer un tableau vide, mais le second
peut être utilisé dans des contextes où la déclaration nue n'est pas autorisée (et il peut également être utilisé
pour détruire le contenu d'un tableau existant et le réduire à la taille zéro). Ledéployer()la fonction attend un
argument entier positif et peut être utilisée pour créer un tableau de taille prédéfinie ; dans ce cas, les éléments
sont initialisés de manière appropriée sous forme de chaînes vides, de matrices nulles, de listes vides, de groupes
vides ou de tableaux vides. Ledefarray()La fonction prend un nombre variable d'arguments (un ou plusieurs), dont
chacun peut être le nom d'une variable du type approprié ou une expression qui évalue un objet du type
approprié.

Définir et obtenir des éléments


Il existe deux manières de définir la valeur d'un élément de tableau : vous pouvez définir un élément particulier à l'aide de l'index
du tableau, ou vous pouvez ajouter un élément à l'aide de l'opérateur += :

2Cependant, il est possible d'enregistrer des tableaux "invisiblement" dans le contexte d'une session GUI, du fait qu'ils peuvent être regroupés en bundles
(voir ci-dessous), et que les bundles peuvent être enregistrés dans le cadre d'une "session".
3Il n'était pas possible d'imbriquer des tableaux avant la version 2019d de gretl.
Chapitre 11. Types de données Gretl 93

# premier cas
chaînes S = array(3) S[2] = "chaîne la
seconde"
# alternative
matrices M = null M +=
mnormal(T,k)

Dans la première méthode, l'index doit (bien sûr) être dans les limites ; c'est-à-dire supérieur à zéro et non
supérieur à la longueur actuelle du tableau. Lorsque la deuxième méthode est utilisée, elle étend
automatiquement la longueur du tableau de 1.
Pour obtenir un élément, l'index du tableau doit être utilisé :

# pour S un tableau de chaînes string


s = S[5]
# pour M un tableau de matrices printf
"\n%#12.5g\n", M[1]

Suppression d'éléments

Il existe une contrepartie à l'opérateur += mentionné ci-dessus : -= peut être utilisé pour supprimer un ou plusieurs
éléments spécifiés parcontenuà partir d'un tableau de chaînes. Notez que -= fonctionne sur tous les éléments
correspondants, donc après les instructions suivantes

chaînes S = defarray("a", "a", "b", "a") S -= "a"

Sdevient un tableau à un élément ne contenant que le troisième élément d'origine.

Plus généralement, un index négatif peut être utilisé pour supprimer un élément spécifié d'un tableau de n'importe quel type,
comme dans

chaînes S = defarray("a", "a", "b", "a") S = S[-1]

où seul le premier élément est supprimé. Voir chapitre17pour en savoir plus sur la sémantique des indices
négatifs.

Opérations sur des tableaux entiers

Trois opérateurs sont applicables à des tableaux entiers, mais un seul à des tableaux de type arbitraire (les deux
autres étant limités à des tableaux de chaînes). L'opération généralement disponible s'ajoute. Vous pouvez faire,
par exemple

# pour M1 et M2 les deux tableaux de matrices


matrices BigM = M1 + M2
# ou si vous souhaitez augmenter M1 M1
+= M2

Dans chaque cas, le résultat est un tableau de matrices dont la longueur est la somme des longueurs deM1et M2
—et de même pour les autres types pris en charge.
Les opérateurs spécifiques aux chaînes sont l'union, via ||, et l'intersection, via &&. Étant donné le code suivant,
pourS1etS2les deux tableaux de chaînes,

chaînes Su = S1 || S2 cordes
Si = S1 && S2

le tableauSucontiendra toutes les chaînes dansS1plus tout dansS2qui ne sont pas dansS1,alors queSicontiendra toutes et
seulement les chaînes qui apparaissent dans les deuxS1etS2.
Chapitre 11. Types de données Gretl 94

Tableaux comme arguments de fonction

On peut écrire des fonctions hansl qui prennent comme arguments n'importe lequel des types de tableau, et il est possible de
passer des tableaux comme arguments de fonction sous forme « pointerisée ». De plus, les fonctions hansl peuvent renvoyer
n'importe quel type de tableau. Voici un exemple trivial pour les chaînes :

fonction void printstrings (chaînes *S)


boucle i=1..nelem(S)
printf "élément %d : '%s'\n", i, S[i] endloop

fonction de fin

chaînes de fonctions mkstrs (int n)


chaînes S = tableau(n)
boucle i=1..n
S[i] = sprintf("membre %d", i) endloop

Retour
fonction de fin

chaînes Foo = mkstrs(5)


impression Foo
printstrings(&Foo)

Quelques points méritent d'être notés ici. Premièrement lanelem()fonctionne pour donner le nombre d'éléments dans n'importe
lequel des types de "conteneurs" (listes, tableaux, bundles, matrices). Deuxièmement, si vous faites "imprime Foo"pourFooun
tableau, vous verrez quelque chose comme :

? imprimer Foo
Tableau de cordes, longueur 5

Tableaux imbriqués

Alors que Gretl estdéployerstructure est en soi unidimensionnelle, vous pouvez ajouter des dimensions supplémentaires par
imbrication. Par exemple, le code ci-dessous crée un tableau contenantntableaux demliasses.

tableaux BB = tableau(n)
boucle i=1..n
bundles BB[i] = array(m) endloop

La syntaxe pour définir ou accéder à l'un desn×mbundles (ou leurs membres) est alors sur le modèle
suivant :

BB[i][j].m = I(3)
eval BB[i][j]
eval BB[i][j].m # ou eval BB[i][j]["m"]

où les indices de tableau respectifs sont chacun mis entre crochets.


Les éléments d'un tableau de tableaux doivent (évidemment) tous être des tableaux, mais il n'est pas nécessaire qu'ils
aient un type de contenu commun. Par exemple, le code suivant crée un tableau contenant un tableau de matrices plus
un tableau de chaînes.

tableaux AA = tableau(2) matrices


AA[1] = tableau(3) chaînes AA[2] =
tableau(3)
Chapitre 11. Types de données Gretl 95

Tableaux et faisceaux
Comme mentionné, leempaquetertype est pris en charge par le mécanisme de tableau. De plus, les tableaux (quel que
soit leur type) peuvent être regroupés :

matrices M = array(8)
# définir les valeurs de M[i] ici... bundle
b
bM = M

La «compressibilité» mutuelle des bundles et des arrays signifie qu'il est possible d'aller assez loin dans le terrier du
lapin. . . il est conseillé aux utilisateurs de ne pas s'emballer.

11.9 Le cycle de vie des objets gretl


Création
La façon la plus simple de créer une nouvelle variable de n'importe quel type est dedéclaration, où l'on indique le
type suivi du nom de la variable à créer, comme dans

scalaire X
série y
matrice UN

et ainsi de suite. Dans ce cas, l'objet en question reçoit une initialisation par défaut, comme suit : un nouveau scalaire a pour
valeurN / A (manquant); une nouvelle série est remplie deN / As ; une nouvelle matrice est nulle (zéro lignes et colonnes) ; une
nouvelle chaîne est vide ; une nouvelle liste n'a pas de membres, les nouveaux bundles et les nouveaux tableaux sont vides.

La déclaration peut être complétée par une initialisation définie, comme dans

scalaire x = pi
série y = log(x) matrice A =
zéros(10,4)

Le type d'une nouvelle variable peut être laissé implicite, comme dans

X = a/100
z = 3.5

Ici le type deXsera déterminé automatiquement en fonction du contexte. Siyest un scalaire, une série ou
une matriceXva héritervouss type (sinon une erreur sera générée, car la division ne s'applique qu'à ces
types). La nouvelle variablezsera "naturellement" de type scalaire.
En général, cependant, nous vous recommandons d'indiquer explicitement le type d'une nouvelle variable. Cela rend
l'intention plus claire pour un lecteur du script et protège également contre les erreurs qui pourraient autrement être
difficiles à comprendre (c'est-à-dire qu'une certaine variable s'avère être du mauvais type pour un calcul ultérieur, mais
vous ne le remarquez pas au début parce que vous n'avez pas dit quel type vous vouliez). Des exceptions à cette règle
pourraient raisonnablement être accordées pour des cas clairs et simples où il y a peu de possibilité de confusion.

Modification
En règle générale, les valeurs des variables de tous types sont modifiées par affectation, en utilisant l'opérateur =
avec le nom de la variable à gauche et une valeur ou une formule appropriée à droite :

z = normale()
x = 100 * log(y) - log(y(-1)) M = qform(a,
X)
Chapitre 11. Types de données Gretl 96

Par valeur « appropriée », nous entendons une valeur conforme au type en question. Une variable gretl acquiert son type
lorsqu'elle est créée pour la première fois et cela ne peut pas être modifié via l'affectation ; par exemple, si vous avez une
matriceUNet plus tard veulent une chaîneUN,vous devrez d'abord supprimer la matrice.

☞Un point à surveiller dans les scripts gretl concerne les conflits de type liés aux noms de séries importés à partir d'un fichier de
données. Par exemple, dans la mise en place d'une boucle de commande (voir chapitre13) il est très courant d'appeler l'index de boucleje.
Maintenant, un index de boucle est un scalaire (généralement incrémenté à chaque tour de boucle). Si vous ouvrez un fichier de données
contenant une série nomméejevous obtiendrez une erreur de type ("Types non conformes pour le fonctionnement") lorsque vous essayez
d'utiliserjecomme index de boucle.

Bien que le type d'une variable existante ne puisse pas être changé à la volée, gretl essaie néanmoins d'être le
plus « compréhensif » possible. Par exemple siXest une série existante et vous dites

x = 100

gretl donnera à la série une valeur constante de 100 plutôt que de se plaindre que vous essayez d'attribuer un scalaire à
une série. Ce problème est particulièrement pertinent pour le type de matrice - voir le chapitre17 pour plus de détails.

Outre l'utilisation de l'opérateur d'affectation standard, vous avez également la possibilité d'utiliser un signe égal
"infléchi", comme dans le langage de programmation C. C'est un raccourci pour le cas où la nouvelle valeur de la
variable est une fonction de l'ancienne valeur. Par exemple,

x += 100 # en caractères longs : x = x + 100 x *=


100 # en caractères longs : x = x * 100

Pour les variables scalaires, vous pouvez utiliser un raccourci plus condensé pour un simple incrément ou décrément de
1, à savoir suivi ++ ou -- respectivement :

x = 100
X-- # x est maintenant égal à 99
x++ # x est maintenant égal à 100

Dans le cas d'objets contenant plusieurs valeurs (séries, matrices et ensembles), vous pouvez modifier des valeurs
particulières dans l'objet à l'aide d'une expression entre crochets pour identifier les éléments auxquels accéder. Nous en
avons discuté ci-dessus pour le type de bundle et le chapitre17va dans les détails pour les matrices. En ce qui concerne
les séries, il existe deux manières de spécifier des valeurs particulières à modifier : vous pouvez utiliser un simple index
de base 1, ou si l'ensemble de données est une série chronologique ou un panel (ou s'il comporte des chaînes de
marqueurs qui identifient les observations), vous pouvez utiliser une chaîne d'observation appropriée. De telles chaînes
sont affichées par gretl lorsque vous imprimez des données avec le --byobsdrapeau. Exemples:

x[13] = 100 # indice simple : la 13ème observation


x[1995:4] = 100 # date : série chronologique trimestrielle
x[2003:08] = 100 # date : série chronologique mensuelle
x["AZ"] = 100 # l'observation avec la chaîne de marqueur "AZ"
x[3:15] = 100 # panneau : la 15ème observation pour la 3ème unité

Notez qu'avec les séries chronologiques trimestrielles ou mensuelles, il n'y a pas d'ambiguïté entre un simple numéro d'index et
une date, puisque les dates contiennent toujours un signe deux-points. Cependant, avec les données de séries chronologiques
annuelles, une telle ambiguïté existe et elle est résolue par la règle selon laquelle un nombre entre parenthèses est toujours lu
comme un simple indice :x[1905]signifie la dix-neuf cent cinquième observation,pasl'observation pour l'année 1905. Vous pouvez
spécifier une année par citation, comme dansx["1905"].

Destruction
Objets des types discutés ci-dessus,à l'exception importante des listes nommées, sont tous détruits à l'aide
dusupprimercommande:supprimernom_objet.
Chapitre 11. Types de données Gretl 97

Les listes sont une exception pour cette raison : dans le contexte des commandes gretl, une liste nommée s'étend aux numéros
d'identification de la série de membres, donc si vous dites

supprimer L

pourLune liste, l'effet est de supprimer toutes les séries dansL;la liste elle-même n'est pas détruite, mais finit par être
vide. Pour supprimer la liste elle-même (sans supprimer la série de membres), vous devez inverser la commande et
utiliser lalistemot-clé:

liste L supprimer

Notez que lesupprimerla commande ne peut pas être utilisée dans unboucleconstruction (voir chapitre13).
Chapitre 12

Variables discrètes

Lorsqu'une variable ne peut prendre qu'un nombre fini, généralement petit, de valeurs, on dit qu'elle estdiscret. Dans gretl, les
variables de type série (uniquement) peuvent être marquées comme discrètes. (Lorsque nous parlons de « variables » ci-dessous,
cela doit être compris comme faisant référence à des séries.) Certaines commandes gretl agissent d'une manière légèrement
différente lorsqu'elles sont appliquées à des variables discrètes ; de plus, gretl fournit quelques commandes qui ne s'appliquent
qu'aux variables discrètes. Plus précisément, lesimuleretxtabcommandes (voir ci-dessous) ne sont disponibles que pour les
variables discrètes, tandis que lesfréquence (distribution de fréquence) produit une sortie différente pour les variables discrètes.

12.1 Déclarer des variables comme discrètes

Gretl utilise une heuristique simple pour juger si une variable donnée doit être traitée comme discrète, mais vous avez
également la possibilité de marquer explicitement une variable comme discrète, auquel cas la vérification heuristique est
contournée.

L'heuristique est la suivante : premièrement, toutes les valeurs de la variable sont-elles « raisonnablement rondes
», ce qui signifie qu'elles sont toutes des multiples entiers de 0,25 ? Si ce critère est rempli, on se demande alors si
la variable prend un ensemble « assez petit » de valeurs distinctes, où « assez petit » est défini comme inférieur ou
égal à 8. Si les deux conditions sont satisfaites, la variable est automatiquement considérée discret.

Pour marquer une variable comme discrète, vous avez deux options.

1. Dans l'interface graphique, sélectionnez "Variable, Modifier les attributs" dans le menu. Une boîte de dialogue
apparaîtra et, si la variable semble appropriée, vous verrez une case à cocher intitulée "Traiter cette variable
comme discrète". Cette boîte de dialogue peut également être appelée via le menu contextuel (clic droit sur une
variable) ou en appuyant sur la touche F2.

2. Depuis l'interface de ligne de commande, via lediscretcommande. La commande prend un ou plusieurs


arguments, qui peuvent être des variables ou une liste de variables. Par exemple:

liste xlist = x1 x2 x3 discrète


z1 xlist z2

Cette syntaxe permet de déclarer aussi discrètement plusieurs variables à la fois, ce qui n'est actuellement
pas possible via l'interface graphique. L'interrupteur --inverseinverse la déclaration d'une variable comme
discrète, ou en d'autres termes la marque comme continue. Par exemple:

foo discret
# maintenant foo est discret
discret foo --reverse
# maintenant foo est continu

La variante en ligne de commande est plus puissante, en ce sens que vous pouvez marquer une variable comme discrète
même si elle ne semble pas convenir à ce traitement.

Notez que marquer une variable comme discrète n'affecte pas son contenu. Il est de la responsabilité de l'utilisateur de
s'assurer que marquer une variable comme discrète est une chose sensée à faire. Notez que si vous souhaitez recoder
une variable continue en classes, vous pouvez utiliser la fonctionnalité arithmétique de gretl, comme dans l'exemple
suivant :

98
Chapitre 12. Variables discrètes 99

données nulles 100


# générer une série avec moyenne 2 et variance 1 série x =
normal() + 2
# divisé en 4 classes série z = (x>0) + (x>2) +
(x>4)
# maintenant déclarer z comme z
discret discret

Une fois qu'une variable est marquée comme discrète, ce paramètre est mémorisé lorsque vous enregistrez le fichier de données.

12.2 Commandes pour variables discrètes


Lesimulercommande
Lesimulerla commande prend comme argument une sérieXet crée des variables factices pour chaque
valeur distincte présente dansX, qui doit avoir déjà été déclaré comme discret. Exemple:

ouvrir greene22_2
discret Z5 # marquer Z5 comme discret Z5
fictif

L'effet de la commande ci-dessus est de générer 5 nouvelles variables factices, étiquetéesDZ5_1à travers DZ5_5,
qui correspondent aux différentes valeurs deZ5.Par conséquent, la variableDZ5_4vaut 1 siZ5vaut 4 et 0 sinon.
Cette fonctionnalité est également disponible via l'interface graphique en sélectionnant l'élément de menu
"Ajouter, Factices pour les variables discrètes sélectionnées".
LesimulerLa commande peut également être utilisée avec la syntaxe suivante :

liste dlist = dummify(x)

Cela crée non seulement les variables factices, mais également une liste nommée (voir la section15.1) qui peut être utilisé
par la suite. L'exemple suivant calcule des statistiques récapitulatives pour la variableOuipour chaque valeur deZ5 :

ouvrir greene22_2
discret Z5 # marquer Z5 comme liste discrète
foo = dummify(Z5)
boucle foreach i foo
smpl $i --restrict --replace summary Y

boucle d'extrémité

spl --full

Depuissimulergénère une liste, il peut être utilisé directement dans les commandes qui appellent une liste en entrée, telles que
ols.Par exemple:

ouvrir greene22_2
discret Z5 # marquer Z5 comme discret ols Y
0 dummify(Z5)

Lefréquencecommande

LefréquenceLa commande affiche les fréquences absolues et relatives pour une variable donnée. La façon dont
les fréquences sont comptées dépend du fait que la variable est continue ou discrète. Cette commande est
également disponible via l'interface graphique en sélectionnant l'entrée de menu "Variable, Distribution de
fréquence".
Chapitre 12. Variables discrètes 100

Pour les variables discrètes, les fréquences sont comptées pour chaque valeur distincte prise par la variable. Pour les
variables continues, les valeurs sont regroupées en « cases », puis les fréquences sont comptées pour chaque case. Le
nombre de bacs, par défaut, est calculé en fonction du nombre d'observations valides dans l'échantillon actuellement
sélectionné via la règle indiquée dans le tableau12.1. Cependant, lorsque la commande est invoquée via l'élément de
menu "Variable, Frequency Plot", cette valeur par défaut peut être remplacée par l'utilisateur.

Observations Bacs
8≤n <16 5
16≤n <50 7

50≤n≤850 ⌈n⌉
n >850 29

Tableau 12.1 :Nombre de bacs pour différentes tailles d'échantillons

Par exemple, le code suivant

ouvrir greene19_1
fréquence TUCE
discret TUCE # marquer TUCE comme fréquence
discrète TUCE

donne

Lire le fichier de données /usr/local/share/gretl/data/greene/greene19_1.gdt


périodicité : 1, maxobs : 32,
plage d'observations : 1-32

Liste 5 variables :
0) const 1) GPA 2) TUCE 3) psi 4) CLASSE

? fréquence TUCE

Distribution de fréquence pour TUCE, obs 1-32 nombre de bacs =


7, moyenne = 21,9375, sd = 3,90151

intervalle midpt fréquence rél. sperme.

< 13.417 12.000 1 3,12 % 3,12 % *


13.417 - 16.250 14.833 1 3,12 % 6,25 % *
16.250 - 19.083 17.667 6 18,75 % 25,00 % ******
19.083 - 21.917 20.500 6 18,75 % 43,75 % ******
21.917 - 24.750 23.333 9 28,12 % 71,88% **********
24.750 - 27.583 26.167 7 21,88% 93,75 % *******
>= 27.583 29.000 2 6,25 % 100.00% **

Test de l'hypothèse nulle de la distribution normale : Chi-carré(2) =


1,872 avec valeur de p 0,39211 ? discret TUCE # marquer TUCE
comme discret
? fréquence TUCE

Répartition des fréquences pour TUCE, obs 1-32

fréquence rél. sperme.

12 1 3,12 % 3,12 % *
14 1 3,12 % 6,25 % *
17 3 9,38% 15,62 % * * *
Chapitre 12. Variables discrètes 101

19 3 9,38% 25,00 % ***


20 2 6,25 % 31,25% **
21 4 12,50 % 43,75 % ****
22 2 6,25 % 50.00% **
23 4 12,50 % 62,50% ****
24 3 9,38% 71,88% ***
25 4 12,50 % 84,38% ****
26 2 6,25 % 90,62 % **
27 1 3,12 % 93,75 % *
28 1 3,12 % 96,88 % *
29 1 3,12 % 100.00% *

Test pour l'hypothèse nulle de la distribution normale : Chi-


carré(2) = 1,872 avec valeur de p 0,39211

Comme le montre l'exemple de sortie, un test de normalité de Doornik-Hansen est calculé


automatiquement. Ce test est supprimé pour les variables discrètes dont le nombre de valeurs distinctes
est inférieur à 10.
Cette commande accepte deux options : --calme,pour éviter la génération de l'histogramme lorsqu'il est invoqué depuis
la ligne de commande et --gamma,pour remplacer le test de normalité par le test non paramétrique de Locke, dont
l'hypothèse nulle est que les données suivent une distribution Gamma.

Si les valeurs distinctes d'une variable discrète doivent être sauvegardées, levaleurs()une construction matricielle peut être
utilisée (voir chapitre17).

Lextabcommande
LextabLa commande cab peut être invoquée de l'une des manières suivantes. D'abord,

xtab ylist ; xlist

oùylistetxlistsont des listes de variables discrètes. Cela produit des tableaux croisés (fréquences à double
sens) de chacune des variables dansylist (par ligne) par rapport à chacune des variables dexlist (par
colonne). Ou deuxième,

xtab xlist

Dans le second cas, un ensemble complet de tableaux croisés est généré ; c'est-à-dire que chaque variable dans
xlistsont tabulées les unes contre les autres variables de la liste. Dans l'interface graphique, cette commande est
représentée par l'item « Cross Tabulation » du menu View, qui est actif si au moins deux variables sont
sélectionnées.
Voici un exemple d'utilisation :

ouvrir greene22_2
discret Z* # marque Z1-Z8 comme xtab discret Z1
Z4 ; Z5 Z6

qui produit

Tableau croisé de Z1 (lignes) contre Z5 (colonnes)

[ 1][ 2][ 3][ 4][ 5] TOT.

[ 0] 20 91 75 93 36 315
[ 1] 28 73 54 97 34 286

TOTAL 48 164 129 190 70 601


Chapitre 12. Variables discrètes 102

Test du chi carré de Pearson = 5,48233 (4 dl, valeur de p = 0,241287)

Tableau croisé de Z1 (lignes) contre Z6 (colonnes)

[ 9][ 12][ 14][ 16][ 17][ 18][ 20] TOT.

[ 0] 4 36 106 70 52 45 2 315
[ 1] 3 8 48 45 37 67 78 286

TOTAL 7 44 154 115 89 112 80 601

Test du chi carré de Pearson = 123,177 (6 df, valeur p = 3,50375e-24)

Tableau croisé de Z4 (lignes) contre Z5 (colonnes)

[ 1][ 2][ 3][ 4][ 5] TOT.

[ 0] 17 60 35 45 14 171
[ 1] 31 104 94 145 56 430

TOTAL 48 164 129 190 70 601

Test du chi carré de Pearson = 11,1615 (4 dl, valeur p = 0,0248074)

Tableau croisé de Z4 (lignes) contre Z6 (colonnes)

[ 9][ 12][ 14][ 16][ 17][ 18][ 20] TOT.

[ 0] 1 8 39 47 30 32 14 171
[ 1] 6 36 115 68 59 80 66 430

TOTAL 7 44 154 115 89 112 80 601

Test du chi carré de Pearson = 18,3426 (6 dl, valeur p = 0,0054306)

Pearsonχ2le test d'indépendance s'affiche automatiquement, à condition que toutes les cellules aient des fréquences
attendues sous indépendance supérieures à 10−7. Cependant, une règle empirique commune stipule que cette
statistique n'est valide que si la fréquence attendue est de 5 ou plus pour au moins 80 % des cellules. Si cette condition
n'est pas remplie, un avertissement est imprimé.

De plus, le --ligneou --colonnedes options peuvent être données : dans ce cas, la sortie affiche respectivement les
pourcentages de ligne ou de colonne.

Si vous voulez couper et coller la sortie dextabà un autre programme, par exemple une feuille de calcul,
vous pouvez utiliser le --des zérosoption; cette option fait que les cellules avec une fréquence nulle affichent
le nombre 0 au lieu d'être vides.
Chapitre 13

Constructions de boucle

13.1 Présentation
La commandeboucleouvre un mode spécial dans lequel gretl accepte qu'un bloc de commandes soit répété zéro
ou plusieurs fois. Cette fonctionnalité peut être utile, entre autres, pour les simulations de Monte Carlo,
l'amorçage des statistiques de test et les procédures d'estimation itératives. La forme générale d'une boucle est :

expression_contrôle_boucle [ --progressive | --verbeux ]


boucle corps
boucle d'extrémité

Cinq formes d'expression de contrôle sont disponibles, comme expliqué dans la section13.2.

Toutes les commandes gretl ne sont pas disponibles dans les boucles ; les commandes qui ne sont pas actuellement acceptées dans ce
contexte sont indiquées dans le tableau13.1.

Tableau 13.1 :Commandes non utilisables dans les boucles

fonction inclure nulldata quitter exécuter setmiss

Par défaut, legenreLa commande fonctionne silencieusement dans le contexte d'une boucle (sans afficher d'informations
sur la variable générée). Pour forcer l'impression des commentaires, vous pouvez spécifier le --verbeux possibilité de
boucle.

Le --progressivepossibilité debouclemodifie le comportement des commandesimprimeretmagasin, et certaines


commandes d'estimation, d'une manière qui peut être utile avec les analyses de Monte Carlo (voir la section13.4).

Les sections suivantes expliquent les différentes formes de l'expression de contrôle de boucle et fournissent quelques exemples
d'utilisation de boucles.

☞ Si vous effectuez une analyse Monte Carlo substantielle avec plusieurs milliers de répétitions, la capacité de mémoire et le temps de
traitement peuvent être un problème. Pour minimiser l'utilisation des ressources informatiques, exécutez votre script à l'aide du
programme de ligne de commande, gretlcli, avec la sortie redirigée vers un fichier.

13.2 Variantes de contrôle de boucle

Boucle de comptage

La forme la plus simple de contrôle de boucle est une spécification directe du nombre de fois que la boucle doit être répétée.
Nous appelons cela une « boucle de comptage ». Le nombre de répétitions peut être une constante numérique, comme dans
boucle 1000,ou peut être lu à partir d'une variable scalaire, comme dansrépliques en boucle.

Dans le cas où le nombre de boucles est donné par une variable, disonsrépliques,dans l'idéerépliquesest un
entier ; si la valeur n'est pas entière, elle est convertie en entier par troncature. Noter querépliquesn'est évalué
qu'une seule fois, lors de la compilation initiale de la boucle.

103
Chapitre 13. Constructions de boucles 104

Boucle tant que

Un deuxième type d'expression de contrôle prend la forme du mot-cléalors quesuivi d'une expression
booléenne. Par exemple,

boucle tant que essdiff > .00001

L'exécution des commandes dans la boucle se poursuivra tant que (a) la condition spécifiée est évaluée
comme vraie et (b) le nombre d'itérations ne dépasse pas la valeur de la variable interne loop_maxiter.Par
défaut, cela équivaut à 100000, mais vous pouvez spécifier une valeur différente (ou supprimer la limite) via
leensemblecommande (voirRéférence des commandes Gretl).

Boucle d'index

Une troisième forme de contrôle de boucle utilise une variable d'index, par exempleje.1Dans ce cas, vous spécifiez des valeurs de
début et de fin pour l'index, comme dansboucle i=1..20.

La variable d'index peut être un scalaire préexistant ; si ce n'est pas le cas, la variable est créée
automatiquement et est détruite en sortie de boucle.
L'index peut être utilisé dans le corps de la boucle de deux manières : vous pouvez accéder à la valeur entière dejeou vous
pouvez utiliser sa représentation sous forme de chaîne, $je.

Les valeurs de début et de fin de l'index peuvent être données sous forme numérique, par référence à des variables
scalaires prédéfinies, ou sous forme d'expressions évaluant des scalaires. Dans ces deux derniers cas, les variables sont
évaluées une fois, au début de la boucle. De plus, avec les données de séries chronologiques, vous pouvez donner les
valeurs de début et de fin sous forme de dates, comme dansboucle i=1950:1..1999:4pour les données trimestrielles.

Cette forme de contrôle de boucle est destinée à être rapide et facile, et en tant que telle, elle est soumise à certaines
limitations. En particulier, le comportement standard consiste à incrémenter la variable index de un à chaque itération.
Ainsi, par exemple, si vous avez

boucle i=m..n

oùmetnsont des variables scalaires avec des valeursm>nlors de l'exécution, l'index ne sera pas décrémenté ; au
lieu de cela, la boucle sera simplement contournée.
Une modification de ce comportement est prise en charge, via l'indicateur d'option --décr (ou -dpour faire court).
Cela entraîne la décrémentation de l'index de un à chaque itération. Par exemple,

boucle i=m..n --decr

Dans ce cas, la boucle sera contournée sim<n.m.Si vous avez besoin d'un contrôle plus flexible, consultez le "pour"formulaire ci-dessous.

La boucle d'index est particulièrement utile en conjonction avec lavaleurs()fonction matricielle lorsqu'une
opération doit être effectuée pour chaque valeur d'une variable discrète (voir chapitre12). Considérez
l'exemple suivant :

ouvrir greene22_2
discret Z8
v8 = valeurs(Z8)
boucle i=1..lignes(v8)
scalaire xi = v8[i]
smpl Z8==xi --restrict --replace
printf "moyenne(Y | Z8 = %g) = %8.5f, sd(Y | Z8 = %g) = %g\n", \
xi, moyenne(Y), xi, sd(Y)
boucle d'extrémité

1Il est de pratique courante en programmation d'utiliser des noms simples à un caractère pour ces variables.
Chapitre 13. Constructions de boucles 105

Dans ce cas, nous évaluons la moyenne conditionnelle et l'écart type de la variableOuipour chaque valeur
deZ8.

Boucle Foreach

La quatrième forme de contrôle de boucle utilise également une variable d'index, dans ce cas pour indexer un ensemble
spécifié de chaînes. La boucle est exécutée une fois pour chaque chaîne de la liste. Cela peut être utile pour effectuer des
opérations répétitives sur une liste de variables. Voici un exemple de syntaxe :

boucle foreach i pêche poire prune


imprimer "$i"
boucle d'extrémité

Cette boucle s'exécutera trois fois, en imprimant "pêche", "poire" et "prune" sur les itérations respectives.
La valeur numérique de l'indice commence à 1 et est incrémentée de 1 à chaque itération.
Si vous souhaitez parcourir une liste de variables contiguës dans l'ensemble de données, vous pouvez donner les noms
des première et dernière variables de la liste, séparés par "..", plutôt que d'avoir à saisir tous les noms. Par exemple,
disons que nous avons 50 variablesAK, AL, . . . , WY,contenant les niveaux de revenu pour les États des États-Unis. Pour
exécuter une régression des revenus dans le temps pour chacun des états, nous pourrions faire :

temps de genre
boucle foreach i AL..WY
ols $i boucle de fin de
temps const

Cette variante de boucle peut également être utilisée pour boucler sur les éléments d'unliste nommée(voir chapitre15).
Par exemple:

liste ylist = y1 y2 y3 boucle


pour chaque i ylist
ols $i const x1 x2
endloop

Notez que si vous utilisez cet idiome dans une fonction (voir chapitre14), en boucle sur une liste qui a été fournie à
la fonction en tant qu'argument, il est nécessaire d'utiliser la syntaxeliste de noms.$ipour référencer les variables
membres de la liste. Dans le contexte de l'exemple ci-dessus, cela reviendrait à remplacer la troisième ligne par

ols ylist.$i const x1 x2

Deux autres cas sont pris en charge : la cible depour chaquepeut être un tableau nommé de chaînes ou un bundle (voir
chapitre11). Dans le cas du tableau, $jeobtient (naturellement) la chaîne à la positionjedans le tableau, de 1 au nombre
d'éléments ; dans le cas du bundle, il obtient les chaînes de clés de tous les membres du bundle (sans ordre particulier).
Pour un forfaitb,la commande "imprimer b"donne un compte rendu assez succinct de l'appartenance au groupe ; pour
un compte complet vous pouvez faire :

boucle foreach ib
imprimer "$je :"
eval b["$i"]
boucle d'extrémité

Pour la boucle

La dernière forme de contrôle de boucle émule lepourdéclaration dans le langage de programmation C. La


syntaxe estboucle pour,suivi de trois expressions composantes, séparées par des points-virgules et
entourées de parenthèses. Les trois composants sont les suivants :
Chapitre 13. Constructions de boucles 106

1. Initialisation : Elle n'est évaluée qu'une seule fois, au début de la boucle. Exemple courant : définir une
variable de contrôle scalaire sur une valeur de départ.

2. Condition de continuation : elle est évaluée au début de chaque itération (y compris la première). Si
l'expression est évaluée comme vraie (non nulle), l'itération continue, sinon elle s'arrête. Exemple courant :
une inégalité exprimant une borne sur une variable de contrôle.

3. Modificateur : une expression qui modifie la valeur d'une variable. Ceci est évalué avant de vérifier la
condition de continuation, à chaque itération après la première. Exemple courant : une variable de
contrôle est incrémentée ou décrémentée.

Voici un exemple simple :

boucle pour (r=0.01 ; r<.991 ; r+=.01)

Dans cet exemple, la variablerprendra les valeurs 0.01, 0.02, . . . , 0,99 sur les 99 itérations. Notez qu'en raison de
la précision finie de l'arithmétique à virgule flottante sur les ordinateurs, il peut être nécessaire d'utiliser une
condition de continuation telle que ci-dessus,r<.991,plutôt que le plus "naturel"r<=.99. (En utilisant des nombres à
double précision sur un processeur x86, au point où vous vous attendezrpour être égal à 0,99, il peut en fait avoir
une valeur de 0,990000000000001.)
L'une ou l'ensemble des trois expressions régissant unpourboucle peut être omise - la forme minimale est (;;).Si le
test de continuation est omis, il est implicitement vrai, vous avez donc une boucle infinie à moins que vous
n'organisiez une autre issue, telle qu'uncasserdéclaration (voir section13.3dessous).
Si l'expression d'initialisation dans unpourboucle prend la forme courante de définir une variable scalaire sur une valeur donnée,
la représentation sous forme de chaîne de la valeur de ce scalaire est rendue disponible dans la boucle via l'accesseur $nom de
la variable.

13.3 Contrôles spéciaux


Outre le contrôle offert par l'expression gouvernante en haut d'une boucle, le flux d'exécution peut être
ajusté via les mots-cléscasseretcontinuer.
Lecassermot-clé termine immédiatement l'exécution de la boucle en cours, tandis quecontinuera pour effet
de sauter toutes les instructions suivantes dans la boucle sur l'itération en cours ; l'exécution passera à
l'itération suivante si la condition de continuation est toujours satisfaite.

13.4 Mode progressif


Si la --progressiveoption est donnée pour une boucle de commande, un comportement spécial est invoqué pour
certaines commandes, à savoir,imprimer, stockeret des commandes d'estimation simples. Par "simples", nous
entendons ici des commandes qui (a) estiment une seule équation (par opposition à un système d'équations) et
(b) le font au moyen d'une seule instruction de commande (par opposition à un bloc d'instructions, comme avec
nlset mle).Le paradigme estols ;d'autres possibilités incluenttsls, wls, logitet ainsi de suite.
Le comportement spécial est le suivant.

Estimateurs : les résultats de chaque itération individuelle de l'estimateur ne sont pas imprimés. Au lieu de
cela, une fois la boucle terminée, vous obtenez une impression de (a) la valeur moyenne de chaque
coefficient estimé pour toutes les répétitions, (b) l'écart type de ces estimations de coefficient, (c) la valeur
moyenne de l'erreur type estimée pour chaque coefficient, et (d) l'écart type des erreurs types estimées.
Notez que cela n'est utile que s'il y a une entrée aléatoire à chaque étape.
imprimer:Lorsque cette commande est utilisée pour imprimer la valeur d'une variable, sa valeur n'est pas imprimée à
chaque tour de boucle. Au lieu de cela, lorsque la boucle est terminée, vous obtenez une impression de la moyenne et de
l'écart type de la variable, à travers les répétitions de la boucle. Ce mode est destiné à être utilisé
Chapitre 13. Constructions de boucles 107

avec des variables qui ont une valeur scalaire à chaque itération, par exemple la somme des carrés des résidus d'une
régression. Les séries ne peuvent pas être imprimées de cette manière, et les matrices non plus.

magasin:Cette commande écrit les valeurs des scalaires spécifiés, à chaque tour de boucle, dans un fichier spécifié. Ainsi,
il conserve un enregistrement complet de leurs valeurs à travers les itérations. Par exemple, les estimations de
coefficients pourraient être sauvegardées de cette manière afin de permettre un examen ultérieur de leur distribution de
fréquence. Un seul telmagasinpeut être utilisé dans une boucle donnée.

13.5 Exemples de boucle

Exemple de Monte-Carlo

Un exemple simple de boucle de Monte Carlo en mode "progressif" est présenté dans le Listing13.1.

Liste 13.1 :Boucle simple de Monte Carlo[Télécharger▼]

données nulles 50
définir la graine 547
série x = 100 * uniforme()
# ouvre une boucle "progressive", à répéter 100 fois loop 100 --
progressive
série u = 10 * normale()
# construire la série de variables dépendantes
y = 10*x + u
# exécuter la régression
OLS ols y const x
# saisir les estimations de coefficient et le scalaire R-carré a =
$coeff(const)
scalaire b = $coeff(x)
scalaire r2 = $rsq
# organiser l'impression des statistiques sur ces
imprimés ab r2
# et enregistrez les coefficients dans le fichier
store coeffs.gdt ab
boucle d'extrémité

Cette boucle imprimera des statistiques récapitulatives pour leunetbestimations etR2sur les 100 répétitions.
Après avoir exécuté la boucle,coeffs.gdt,qui contient les estimations de coefficients individuels de toutes les
séries, peut être ouvert dans gret pour examiner en détail la distribution de fréquence des estimations.

Ledonnées nullesLa commande est utile pour le travail de Monte Carlo. Au lieu d'ouvrir un "vrai" ensemble de données,
nulldata 50 (par exemple) crée un jeu de données artificiel, contenant juste une constante et une variable d'indice, avec
50 observations. Des variables construites peuvent alors être ajoutées. Voir leensemblepour obtenir des informations sur
la génération de séries pseudo-aléatoires répétables.

Moindres carrés itérés


Référencement13.2utilise une boucle "while" pour répliquer l'estimation d'une fonction de consommation non linéaire de la
forme
C = α+βYγ+ϵ
tel que présenté dansGreen(2000), Exemple 11.3. Ce script est inclus dans la distribution gretl sous le nom
greene11_3.inp ;vous pouvez le trouver dans gretl sous l'élément de menu "Fichier, Fichiers de script, Exemples de
scripts, Greene...".
Chapitre 13. Constructions de boucles 108

L'option --impression finalepour leolsLa commande organise les choses de sorte que les résultats de la régression
ne soient pas imprimés à chaque tour de boucle, mais les résultats de la régression sur la dernière itération
seront imprimés à la fin de la boucle.

Listing 13.2 :Fonction de consommation non linéaire[Télécharger▼]

ouvrir greene11_3.gdt
# courir MCO initial
ols C 0 Y
scalaire essbak = $ess scalaire
essdiff = 1 scalaire beta =
$coeff(Y) scalaire gamma = 1

# itérer OLS jusqu'à ce que la somme des carrés de l'erreur converge


pendant que essdiff > .00001
# forme les variables linéarisées
série C0 = C + gamma * beta * Y^gamma * log(Y) série x1 =
Y^gamma
série x2 = bêta * Y^gamma * log(Y)
# exécuter OLS
ols C0 0 x1 x2 --print-final --no-df-corr --vcv beta
= $coef[2]
gamma = $coef[3]
ess = $ess
essdiff = abs(ess - essbak)/essbak essbak = ess

boucle d'extrémité

# affiche les estimations des paramètres en utilisant leurs "noms propres"


printf "alpha = %g\n", $coeff[1]
printf "bêta = %g\n", bêta printf
"gamma = %g\n", gamma

Référencement13.3montre comment une boucle peut être utilisée pour estimer un modèle ARMA, en exploitant la
régression du « produit extérieur du gradient » (OPG) discutée parDavidson et MacKinnon(1993).

D'autres exemples debouclel'utilisation qui peut être d'intérêt peut être trouvée dans le chapitre21.
Chapitre 13. Constructions de boucles 109

Listing 13.3 :ARMA 1, 1[Télécharger▼]

# Estimation d'un modèle ARMA(1,1) "manuellement", à l'aide d'une boucle

ouvrir arma.gdt

scalaire c = 0
scalaire a = 0,1
scalaire m = 0,1

série e = 0,0
série de_c = e
série de_a = e
série de_m = e

scalaire critique = 1

boucle tant que crit > 1.0e-9


# erreurs de prévision en une étape e =
y - c - a*y(-1) - m*e(-1)

# log-vraisemblance
scalaire loglik = -0.5 * sum(e^2) imprimer
loglik

# partiels de e par rapport à c, a et m de_c = -1 - m *


de_c(-1)
de_a = -y(-1) -m * de_a(-1) de_m =
-e(-1) -m * de_m(-1)

# partiels de l par rapport aux séries c, a et m sc_c = -de_c


*e
série sc_a = -de_a * e série sc_m
= -de_m * e

# Régression OPG
ols const sc_c sc_a sc_m --print-final --no-df-corr --vcv

# Mise à jour Les paramètres


c + = $coeff[1]
un+ = $coef[2]
m + = $coef[3]

# afficher la progression
printf " constant = %.8g (dégradé %#.6g)\n", c, $coeff[1]
printf " coefficient ar1 = %.8g (pente %#.6g)\n", a, $coeff[2] coefficient ma1 = %.8g
printf " (pente %#.6g)\n", m, $coeff[3]

crit = $T - $ess print


crit
boucle d'extrémité

scalaire se_c = $stderr[1] scalaire


se_a = $stderr[2] scalaire se_m =
$stderr[3]

printf "\n"
printf "constante = %.8g (se = %#.6g, t = %.4f)\n", c, se_c, c/se_c
printf "coefficient ar1 = %.8g (se = %#.6g, t = %.4f)\n", a, se_a, a/se_a printf "coefficient ma1 = %.8g
(se = %#.6g, t = %.4f)\n", m, se_m, m/se_m
Chapitre 14

Fonctions définies par l'utilisateur

14.1 Définir une fonction


Gretl offre un mécanisme pour définir des fonctions, qui peuvent être appelées via la ligne de commande, dans le
contexte d'un script, ou (si empaqueté de manière appropriée, voir la section14.5) via l'interface graphique du
programme.

La syntaxe pour définir une fonction ressemble à ceci :


fonctiontapez le nom de la fonction(paramètres)
corps de fonction
fonction de fin
La première ligne d'une définition de fonction contient ces éléments, dans un ordre strict :

1. Le mot cléfonction.

2.taper, qui indique le type de valeur renvoyé par la fonction, le cas échéant. Ce doit être l'un desannuler
(si la fonction ne retourne rien),scalaire, série, matrice, liste, chaîne, paquetou l'un des types de
tableau de gretl,matrices, bundles, chaînes (voir section11.8).

3.nomfonction, l'identifiant unique de la fonction. Les noms de fonction ont une longueur maximale de 31
caractères ; ils doivent commencer par une lettre et ne peuvent contenir que des lettres, des chiffres et le
caractère de soulignement. Vous obtiendrez une erreur si vous essayez de définir une fonction portant le même
nom qu'une commande gretl existante.

4. La fonctionparamètres, sous la forme d'une liste séparée par des virgules entre parenthèses. Cela peut être
exécuté dans le nom de la fonction ou séparé par un espace blanc, comme indiqué. Dans le cas où la
fonction ne prend aucun argument (inhabituel, mais acceptable), cela doit être indiqué en plaçant le mot-clé
annulerentre les parenthèses de la liste de paramètres.

Les paramètres de fonction peuvent être de n'importe lequel des types indiqués ci-dessous.1

Taper Description

bourdonner variable scalaire agissant comme un commutateur

entier booléen variable scalaire agissant comme une variable

scalaire scalaire entière

série série de données

liste liste nommée de matrice de

matrice série ou de vecteur

chaîne variable de chaîne ou conteneur polyvalent de


empaqueter littéral de chaîne (voir la section11.7) tableau de
matrices matrices (voir section11.8) tableau de faisceaux
liasses
cordes tableau de chaînes

1Un type de paramètre supplémentaire est disponible pour l'utilisation de l'interface graphique, à savoirobs;cela équivaut àentierà l'exception de la manière
dont il est représenté dans l'interface graphique d'appel d'une fonction.

110
Chapitre 14. Fonctions définies par l'utilisateur 111

Chaque élément de la liste des paramètres doit inclure deux termes : un spécificateur de type et le nom
sous lequel le paramètre doit être connu dans la fonction. Un exemple suit :

fonction scalaire myfunc (série y, liste xvars, bool verbeux)

Chacun des spécificateurs de type, à l'exception delisteetchaîne,peut être modifié en ajoutant un astérisque
au nom du paramètre associé, comme dans

fonction scalaire mafonc (série *y, scalaire *b)

La signification de cette modification est expliquée ci-dessous (voir section14.4); il est lié à l'utilisation
d'arguments de pointeur dans le langage de programmation C.

Paramètres de fonction : raffinements facultatifs

Outre les éléments requis mentionnés ci-dessus, la spécification d'un paramètre de fonction peut inclure certains
champs supplémentaires, comme suit :

• Leconstantemodificateur.

• Pourscalaireouentierparamètres : valeurs minimum, maximum et/ou par défaut ; ou pourbourdonnerparamètres,


juste une valeur par défaut.

• Pour les arguments optionnels autres quescalaire, entieretbouffon,la valeur par défaut spécialenul.

• Pour tous les paramètres, une chaîne descriptive.

• Pourentierparamètres avec des valeurs minimales et maximales spécifiées, un ensemble de chaînes à associer aux
valeurs numériques autorisées (étiquettes de valeur).

Les trois premières de ces options peuvent être utiles dans de nombreux contextes ; les deux derniers peuvent être utiles si une fonction
doit être empaquetée pour être utilisée dans l'interface graphique gretl (mais probablement pas autrement). Nous développons
maintenant chacune des options.

• Leconstantemodificateur : doit être donné comme préfixe à la spécification du paramètre de base, comme dans

matrice constante M

Ceci constitue une promesse que l'argument correspondant ne sera pas modifié dans la fonction ;
gretl signalera une erreur si la fonction tente de modifier l'argument.

• Valeurs minimales, maximales et par défaut pourscalaireouentiertypes : ces valeurs doivent suivre
directement le nom du paramètre, entre crochets et les éléments individuels séparés par des deux-
points. Par exemple, supposons que nous ayons un paramètre entiercommandepour lequel on
souhaite spécifier un minimum de 1, un maximum de 12, et un défaut de 4. On peut écrire

dans l'ordre[1:12:4]

Si vous souhaitez omettre l'un des trois spécificateurs, laissez le champ correspondant vide. Par exemple [1 :: 4]
spécifierait un minimum de 1 et une valeur par défaut de 4 tout en laissant le maximum illimité. Cependant, en
tant que cas particulier, il est acceptable de ne donner qu'une seule valeur, sans deux-points, auquel cas la valeur
est interprétée comme une valeur par défaut. Ainsi par exemple

entier k[0]

désigne une valeur par défaut de 0 pour le paramètrek,sans minimum ni maximum spécifié. Si vous
souhaitez spécifier un minimum de zéro sans maximum ni valeur par défaut, vous devrez écrire
Chapitre 14. Fonctions définies par l'utilisateur 112

entier k[0::]

Pour un paramètre de typeboo (dont les valeurs sont simplement nulles ou non nulles), vous pouvez spécifier une valeur par
défaut de 1 (vrai) ou 0 (faux), comme dans

bool verbeux[0]

• Chaîne descriptive : elle apparaîtra comme une aide à l'utilisateur si la fonction est empaquetée (voir la
section14.5ci-dessous) et appelé via l'interface graphique de gretl. La chaîne doit être entourée de
guillemets doubles et séparée des éléments précédents de la spécification de paramètre par un espace,
comme dans

série y "variable dépendante"

• Étiquettes de valeur : elles ne peuvent être utilisées qu'avecentierparamètres pour lesquels des valeurs minimales
et maximales ont été spécifiées (pour qu'il y ait un nombre fixe de valeurs admissibles) et le nombre d'étiquettes
doit correspondre au nombre de valeurs. Ils apparaîtront dans l'interface graphique sous la forme d'une liste
déroulante, rendant l'intention de l'auteur de la fonction plus claire lorsqu'un argument entier représente une
sélection catégorielle. Un ensemble d'étiquettes de valeur doit être placé entre accolades et les étiquettes
individuelles doivent être placées entre guillemets doubles et séparées par des virgules ou des espaces. Par
exemple:

int case[1:3:1] {"Effets fixes", "Entre modèles", "Effets aléatoires"}

Si au moins deux des champs facultatifs de fin sont indiqués dans une spécification de paramètre, ils doivent être
indiqués dans l'ordre indiqué ci-dessus : min/max/défaut, description, libellés de valeur. Notez qu'il n'y a pas de fonction
pour "échapper" les caractères dans les chaînes descriptives ou les étiquettes de valeur ; ceux-ci peuvent contenir des
espaces mais ils ne peuvent pas contenir de guillemets doubles.

Voici un exemple de spécification de fonction bien formée utilisant tous les éléments mentionnés ci-dessus :

fonction matrice mafonc (série y "variable dépendante",


liste X "régresseurs",
int p[0::1] "ordre de décalage",
int c[1:2:1] "critère" {"AIC", "BIC"}, booléen
silencieux[0])

L'un des avantages de spécifier des valeurs par défaut pour les paramètres, le cas échéant, est qu'en mode script ou
ligne de commande, les utilisateurs peuvent omettre les arguments de fin qui ont des valeurs par défaut. Par exemple,
mafonction ci-dessus pourrait être invoqué avec seulement deux arguments, correspondant àyetX;implicitementp =1,c =
1 etcalmec'est faux.

Fonctions ne prenant aucun paramètre

Vous pouvez définir une fonction qui n'a pas de paramètres (ceux-ci sont appelés "routines" dans certains langages de
programmation). Dans ce cas, utilisez le mot cléannulerà la place de la liste des paramètres :

matrice de fonction myfunc2 (vide)

Le corps de la fonction

Lecorps de fonctionest composé de commandes gretl ou d'appels à des fonctions définies par l'utilisateur (c'est-à-dire que les appels de
fonction peuvent être imbriqués). Une fonction peut s'appeler (c'est-à-dire que les fonctions peuvent être récursives). Bien que le corps de
la fonction puisse contenir des appels de fonction, il ne peut pas contenir de définitions de fonction. Autrement dit, vous ne pouvez pas
définir une fonction à l'intérieur d'une autre fonction. Pour plus de détails, voir rubrique14.4.
Chapitre 14. Fonctions définies par l'utilisateur 113

14.2 Appel d'une fonction


Une fonction utilisateur est appelée en tapant son nom suivi de zéro ou plusieurs arguments entre
parenthèses. S'il y a deux arguments ou plus, ils doivent être séparés par des virgules.
Des vérifications automatiques sont en place pour s'assurer que le nombre d'arguments donnés dans un appel de
fonction correspond au nombre de paramètres et que les types des arguments donnés correspondent aux types
spécifiés dans la définition de la fonction. Une erreur est signalée si l'une de ces conditions n'est pas respectée.
Une réserve : il est permis d'omettre des arguments à la fin de la liste, à condition que des valeurs par défaut
soient spécifiées dans la définition de la fonction. Pour être précis, la vérification est que le nombre d'arguments
est au moins égal au nombre derequisparamètres et n'est pas supérieur au nombre total de paramètres.

En général, un argument à une fonction peut être donné soit comme le nom d'une variable préexistante,
soit comme une expression qui évalue une variable du type approprié.
L'exemple trivial suivant illustre un appel de fonction qui correspond correctement à la définition de fonction
correspondante.

# définition de fonction
fonction scalaire ols_ess (série y, liste xvars)
ols y 0 xvars --quiet printf "ESS =
%g\n", $ess return $ess

fonction de fin

# scénario principal
données ouvertes4-1
liste xlist = 2 3 4
# appel de fonction (la valeur de retour est ignorée ici) ols_ess(price,
xlist)

L'appel de fonction donne deux arguments : le premier est une série de données spécifiée par nom et le second est une
liste nommée de régresseurs. Notez que bien que la fonction offre la somme des erreurs des carrés comme valeur de
retour, elle est ignorée par l'appelant dans cette instance. (En remarque ici, si vous voulez qu'une fonction calcule une
valeur liée à une régression, mais que vous n'êtes pas intéressé par les résultats complets de la régression, vous pouvez
utiliser le --calmedrapeau avec la commande d'estimation comme indiqué ci-dessus.)

Un deuxième exemple montre comment écrire un appel de fonction qui affecte une valeur de retour à une variable dans
l'appelant :

# définition de fonction
série de fonctions get_uhat (série y, liste xvars)
ols y 0 xvars --quiet return
$uhat
fonction de fin

# scénario principal
données ouvertes4-1
liste xlist = 2 3 4
# appel de fonction
series resid = get_uhat(price, xlist)

14.3 Supprimer une fonction


Si vous avez défini une fonction et souhaitez ensuite la vider de la mémoire, vous pouvez le faire en utilisant les
mots cléssupprimerouclair,un péché

fonction myfonc supprimer


fonction obtenir_uhat clair
Chapitre 14. Fonctions définies par l'utilisateur 114

Notez cependant que simafonctionest déjà une fonction définie, à condition qu'une nouvelle définition écrase
automatiquement la précédente, il devrait donc rarement être nécessaire de supprimer explicitement des fonctions.

14.4 Détails de la programmation des fonctions

Variables contre pointeurs


La plupart des arguments des fonctions peuvent être passés de deux manières : "tels quels" ou via des pointeurs (l'exception est
le type de liste, qui ne peut pas être passé en tant que pointeur). Considérons d'abord l'exemple plutôt artificiel suivant :

fonction série triple1 (série x)


retour 3*x
fonction de fin

fonction void triple2 (série *x)


X *=3
fin fonction

nulldata 10
série y = normal() série y3 =
triple1(y) imprimer y3

triple2(&y)
imprimer y

Ces deux fonctions produisent essentiellement le même résultat - les deuximprimerles instructions de l'appelant
afficheront les mêmes valeurs, mais de manière assez différente. Le premier renvoie explicitement une version
modifiée de son entrée (qui doit être une simple série) : après l'appel àtriple1, yest inchangé ; il n'aurait été
modifié que si la valeur de retour avait été réaffectée àyplutôt quey3.La deuxième fonction modifie son entrée
(donnée comme un pointeur vers une série) en place sans réellementretour quoi que ce soit.

Il vaut la peine de noter quetriple2dans l'état actuel des chosespasêtre considéré comme idiomatique en tant que
fonction gretl (bien que ce soit formellement correct). Le point ici est juste d'illustrer la distinction entre passer un
argument de la manière par défaut et sous forme de pointeur.

Pourquoi faire cette distinction ? Il y a deux raisons principales à cela : la modularité et la performance.
Par modularité, nous entendons l'isolation d'une fonction du reste du script qui l'appelle. L'un des nombreux avantages
de cette approche est que vos fonctions sont facilement réutilisables dans d'autres contextes. Pour atteindre la
modularité,les variables créées dans une fonction sont locales à cette fonction et sont détruites lorsque la fonction se
termine, à moins qu'elles ne soient rendues disponibles en tant que valeurs de retour et que ces valeurs soient
"récupérées" ou attribuées par l'appelant. De plus, les fonctions n'ont pas accès aux variables dans la "portée
externe" (c'est-à-dire les variables qui existent dans le script à partir duquel la fonction est appelée) sauf dans la mesure
où celles-ci sont explicitement transmises à la fonction en tant qu'arguments.

Par défaut, lorsqu'une variable est passée à une fonction en tant qu'argument, ce que la fonction "obtient" réellement
est uncopiede la variable externe, ce qui signifie que la valeur de la variable externe n'est pas modifiée par tout ce qui se
passe à l'intérieur de la fonction. Cela signifie que vous pouvez passer des arguments à une fonction sans vous soucier
des éventuels effets secondaires ; en même temps, l'auteur de la fonction peut utiliser des variables d'argument comme
espace de travail sans craindre d'effets perturbateurs au niveau de l'appelant.

L'utilisation de pointeurs, cependant, permet à une fonction et à son appelant de coopérer de sorte qu'une
variable externepeutêtre modifié par la fonction. En effet, cela permet à une fonction de "renvoyer" plus d'une
valeur (bien qu'une seule variable puisse être renvoyée directement, voir ci-dessous). Pour indiquer qu'un objet
particulier doit être passé comme pointeur, le paramètre en question est marqué du préfixe * dans la définition
de la fonction, et l'argument correspondant est marqué du préfixe complémentaire & dans l'appelant. Par
exemple,
Chapitre 14. Fonctions définies par l'utilisateur 115

fonction série get_uhat_and_ess(série y, liste xvars, scalaire *ess)


ols y 0 xvars --quiet ess =
$ess
série euh = $uhat
retour euh
fonction de fin

données ouvertes4-1
liste xlist = 2 3 4 scalaire
SSR
series resid = get_uhat_and_ess(price, xlist, &SSR)

Dans ce qui précède, on peut dire que la fonction reçoit laadressede la variable scalaireRSS,et il attribue une
valeur à cette variable (sous le nom localess). (Pour toute personne habituée à programmer enC : notez qu'il n'est
pas nécessaire, ni même possible, de « déréférencer » la variable en question au sein de la fonction à l'aide de
l'opérateur *. L'utilisation sans fioritures du nom de la variable est suffisante pour accéder à la variable dans la
portée externe.)
Un tel paramètre "adresse" peut être utilisé comme moyen d'offrir des informations facultatives à
l'appelant. (C'est-à-dire que l'argument correspondant n'est pas strictement nécessaire, mais sera utilisé s'il
est présent). Dans ce cas, le paramètre doit recevoir une valeur par défaut denulet la fonction doit tester
pour voir si l'appelant a fourni un argument correspondant ou non, en utilisant la fonction intégréeexiste().
Par exemple, voici la fonction simple montrée ci-dessus, modifiée pour faire le remplissage duess valeur
facultative.

fonction série get_uhat_and_ess(série y, liste xvars, scalaire *ess[null])


ols y 0 xvars --quiet si
existe(s)
ess = moins de $

fin si
retour $ euh
fonction de fin

Si l'appelant ne se soucie pas d'obtenir leessvaleur, il peut utilisernulà la place d'un vrai argument :

série resid = get_uhat_and_ess(price, xlist, null)

Alternativement, les arguments de fin de fonction qui ont des valeurs par défaut peuvent être omis, donc ce qui suit serait
également un appel valide :

série resid = get_uhat_and_ess(price, xlist)

Une limitation à l'utilisation des arguments de type pointeur doit être notée : vous ne pouvez pas fournir une variable donnée
comme argument de pointeur plus d'une fois dans un appel de fonction donné. Par exemple, supposons que nous ayons une
fonction qui prend deux arguments de pointeur de matrice,

fonction scalaire pointfunc (matrice *a, matrice *b)

Et supposons que nous ayons deux matrices,Xety,au niveau de l'appelant. L'appel

fonctionpoint(&x, &y)

est OK, mais l'appel

pointfunc(&x, &x) # ne fonctionnera pas

générera une erreur. C'est parce que la situation à l'intérieur de la fonction deviendrait trop confuse, avec
ce qui est vraiment le même objet existant sous deux noms.
Chapitre 14. Fonctions définies par l'utilisateur 116

Paramètres constants

Les arguments de type pointeur peuvent également être utiles pour optimiser les performances. Même si une variable
n'est pas modifiée à l'intérieur de la fonction, il peut être judicieux de la passer sous forme de pointeur si elle occupe
beaucoup de mémoire. Sinon, le temps passé par gretl à transcrire la valeur de la variable dans la copie locale peut être
non négligeable par rapport au temps passé par la fonction à faire le travail pour lequel elle a été écrite.

Référencement14.1pousse cela à l'extrême. Nous définissons deux fonctions qui renvoient le nombre de lignes d'une
matrice (une opération assez rapide). Le premier obtient une matrice comme argument tandis que le second obtient un
pointeur vers une matrice. Les fonctions sont évaluées 500 fois sur une matrice de 2000 lignes et 2000 colonnes ; sur un
système typique, les nombres à virgule flottante occupent 8 octets de mémoire, de sorte que la taille totale de la matrice
est d'environ 32 mégaoctets.

Exécution du code dans l'exemple14.1produira une sortie similaire à la suivante (les nombres réels
dépendent bien sûr de la machine que vous utilisez):

Temps écoulé:
sans pointeurs (copie) = 2,47197 secondes, avec pointeurs
(pas de copie) = 0,00378627 secondes

Liste 14.1 :Comparaison des performances : valeurs contre pointeur[Télécharger▼]

fonction scalaire rowcount1 (matrice X)


lignes de retour (X)
fonction de fin

fonction scalaire rowcount2 (matrice const *X)


lignes de retour (X)
fonction de fin

verbeux
ensemble

X= zéros (2000,2000)
scalaire r

ensemble chronomètre
boucle 500
r = nombre de lignes1(X)
boucle d'extrémité

e1 = $chronomètre

ensemble chronomètre
boucle 500
r = rowcount2(&X)
boucle d'extrémité

e2 = $chronomètre

printf "Temps écoulé :\n\


sans pointeurs (copie) = %g secondes,\n \ avec pointeurs (pas de
copie) = %g secondes\n", e1, e2

Si un argument de pointeur est utilisé à cette fin — et que l'objet vers lequel pointe le pointeur n'est pas modifié
(est traité en lecture seule) par la fonction — on peut le signaler à l'utilisateur en ajoutant leconstantequalificatif,
comme indiqué pour la fonctionnombre de lignes2dans la liste14.1. Lorsqu'un argument pointeur est qualifié de
cette manière, toute tentative de modification de l'objet dans la fonction génère une erreur.
Cependant, en combinant leconstantedrapeau avec le mécanisme de pointeur est techniquement redondant pour le
Chapitre 14. Fonctions définies par l'utilisateur 117

raison suivante : si vous marquez un argument de matrice commeconstantealors gretl le passera en fait en mode
pointeur en interne (puisqu'il ne peut pas être modifié dans la fonction, il n'y a aucun inconvénient à le rendre
simplement disponible pour la fonction plutôt que de le copier). Ainsi, dans l'exemple ci-dessus, nous pourrions réviser la
signature de la deuxième fonction comme

fonction scalaire rowcount2a (const matrice X)

et appelez-le avecr = nombre de lignes2a(X),pour la même accélération par rapport ànombre de lignes1.

Du point de vue de l'appelant, la deuxième option—utiliser leconstantemodificateursansla notation pointeur est


préférable, car elle permet à l'appelant de transmettre un objet créé "à la volée". Supposons que l'appelant a deux
matrices,UNetB,dans la portée, et souhaite faire passer leur concaténation verticale comme argument. L'appel
suivant fonctionnerait bien :

r = nombre de lignes2a(A|B)

Utilisernombre de lignes2,d'autre part, l'appelant devrait d'abord créer une variable nommée (puisque vous
ne pouvez pas donner "l'adresse" d'un objet anonyme tel queA|B) :

matrice AB = A|B
r = nombre de lignes2(&AB)

Cela nécessite une ligne de code supplémentaire et laisseUN Boccupant la mémoire après l'appel.

Nous avons illustré en utilisant un paramètre matriciel, mais leconstantemodificateur peut être utilisé avec le
même effet - à savoir, l'argument est passé directement, sans être copié, mais est protégé contre toute
modification dans la fonction - pour tous les types qui prennent en charge l'appareil de pointeur.

Liste des arguments

L'utilisation d'une liste nommée comme argument d'une fonction permet de fournir à une fonction un ensemble
de variables dont le nombre est inconnu au moment de l'écriture de la fonction, par exemple des ensembles de
régresseurs ou d'instruments. Au sein de la fonction, la liste peut être transmise à des commandes telles que ols.

Un argument de liste peut également être "décompressé" à l'aide d'unpour chaqueconstruction de boucle, mais cela nécessite
une certaine prudence. Par exemple, supposons que vous ayez une listeXet que vous souhaitez calculer l'écart type de chaque
variable de la liste. Tu peux faire:

boucle foreach i X
scalaire sd_$i = sd(X.$i) endloop

Veuillez noter: une syntaxe spéciale est nécessaire dans ce contexte. Si nous voulions effectuer la tâche ci-dessus sur une liste
dans un script régulier (pas à l'intérieur d'une fonction), nous pourrions faire

boucle foreach i X
scalaire sd_$i = sd($i)
endloop

où $jeobtient le nom de la variable à la positionjedans la liste, etsd($i)obtient son écart-type. Mais à


l'intérieur d'une fonction, travaillant sur une liste fournie en argument, si nous voulons référencer une
variable individuelle dans la liste, nous devons utiliser la syntaxenom_liste.nom_var. Ainsi, dans l'exemple
ci-dessus, nous écrivonssd(X.$i).
Cela est nécessaire pour éviter d'éventuelles collisions entre l'espace de noms de la fonction et l'espace de noms
du script appelant. Par exemple, supposons que nous ayons une fonction qui prend un argument de liste et qui
définit une variable locale appeléey.Supposons maintenant que cette fonction reçoive une liste contenant
Chapitre 14. Fonctions définies par l'utilisateur 118

une variable nomméey.Si les deux espaces de noms n'étaient pas séparés, soit nous aurions une erreur,
soit la variable externeyserait silencieusement écrasé par le local. Il est donc important que les variables
d'arguments de liste ne soient pas "visibles" par leur nom dans les fonctions. Pour «saisir» de telles
variables, vous devez utiliser la forme d'identification mentionnée ci-dessus: le nom de la liste, suivi d'un
point, suivi du nom de la variable.

Constance des arguments de la listeLorsqu'une liste nommée de variables est transmise à une fonction, la
fonction reçoit en fait une copie de la liste. La fonction peut modifier cette copie (par exemple, ajouter ou
supprimer des membres), mais la liste d'origine au niveau de l'appelant n'est pas modifiée.

Arguments de liste facultatifsSi un argument de liste d'une fonction est facultatif, cela doit être indiqué en
ajoutant une valeur par défaut denul,un péché

fonction scalaire mafonc (scalaire y, liste X[null])

Dans ce cas, si l'appelant donnenulcomme argument de la liste (ou omet simplement le dernier argument) la liste
nomméeXà l'intérieur de la fonction sera vide. Cette possibilité peut être détectée à l'aide dunelem() fonction, qui
renvoie 0 pour une liste vide.

Arguments de chaîne

Les arguments de chaîne peuvent être utilisés, par exemple, pour fournir une flexibilité dans la dénomination des
variables créées dans une fonction. Dans l'exemple suivant, la fonctionmavgrenvoie une liste contenant deux moyennes
mobiles construites à partir d'une série d'entrée, avec les noms des variables nouvellement créées régies par l'argument
de chaîne.

liste de fonctions mavg (série y, chaîne vname)


liste retlist = null
chaîne newname = sprintf("%s_2", vname) retlist +=
genseries(newname, (y+y(-1)) / 2) newname = sprintf("%s_4",
vname)
retlist += genseries(nouveaunom, (y+y(-1)+y(-2)+y(-3)) / 4) return retlist

fonction de fin

données ouvertes9-9
list malist = mavg(nocars, "nocars") print malist --
byobs

La dernière ligne du script imprimera deux variables nomméesnocars_2etnocars_4.Pour plus de détails sur la
gestion des chaînes nommées, voir le chapitre15.
Si un argument de chaîne est considéré comme facultatif, on peut lui donner unnulvaleur par défaut, comme dans

fonction scalaire foo (série y, chaîne vname[null])

Récupérer les noms des arguments


Les variables données en arguments à une fonction sont connues à l'intérieur de la fonction par les noms des
paramètres correspondants. Par exemple, au sein de la fonction dont la signature est

fonction void somefun (série y)

nous avons la série ditey.Il peut cependant être utile de pouvoir déterminer les noms des variables fournies
en arguments. Ceci peut être fait en utilisant la fonctionargname,qui prend le nom d'un paramètre de
fonction comme seul argument et renvoie une chaîne. Voici une simple illustration :
Chapitre 14. Fonctions définies par l'utilisateur 119

fonction void namefun (série y)


printf "la série donnée comme 'y' a été nommée %s\n", argname(y) end function

données ouvertes9-7
namefun(QNC)

Cela produit la sortie

la série désignée par 'y' s'appelait QNC

Veuillez noter que cela ne fonctionnera pas toujours : les arguments donnés aux fonctions peuvent être des
variables anonymes, créées à la volée, comme dansfun(log(QNC))ouamusant(IPC/100).Dans ce cas le
nom_argumentfonction renvoie une chaîne vide. Les rédacteurs de fonctions qui souhaitent utiliser cette fonction
doivent vérifier le retour denom_argumenten utilisant lestrlen()fonction : si elle renvoie 0, aucun nom n'a été
trouvé.

Valeurs de retour

Les fonctions peuvent ne rien renvoyer (juste imprimer un résultat, peut-être), ou elles peuvent renvoyer une
seule variable. La valeur de retour, le cas échéant, est spécifiée via une instruction dans le corps de la fonction
commençant par le mot-cléretour,suivi soit du nom d'une variable (qui doit être du type annoncé sur la première
ligne de la définition de la fonction) soit d'une expression qui produit une valeur du type correct.

Le fait qu'une fonction renvoie une liste ou un ensemble est un moyen de permettre le "retour" de plus d'une
variable. Par exemple, vous pouvez définir plusieurs séries dans une fonction et les regrouper sous forme de
liste ; dans ce cas ils ne sont pas détruits à la sortie de la fonction. Voici un exemple simple, qui illustre également
la possibilité de définir les libellés descriptifs des variables générées dans une fonction.

liste de fonctions make_cubes (liste xlist)


liste cubes = boucle nulle
foreach i xlist
series $i3 = (xlist.$i)^3 setinfo $i3 -d
"cube de $i" liste les cubes += $i3

boucle d'extrémité

cubes de retour
fonction de fin

données ouvertes4-1
liste xlist = prix pied carré
list cubelist = make_cubes(xlist) print xlist
cubelist --byobs labels

UNretourL'instruction provoque le retour (sortie) de la fonction au point où elle apparaît dans le corps de la
fonction. Une fonction peut également se terminer lorsque (a) la fin du code de la fonction est atteinte (dans le
cas d'une fonction sans valeur de retour), (b) une erreur gretl se produit, ou (c) unfuncerrdéclaration est atteinte.

Lefuncerrmot-clé — qui peut être suivi d'une chaîne entre guillemets doubles, ou du nom d'une variable de
chaîne, ou de rien — provoque la fermeture d'une fonction avec une erreur signalée. Si une chaîne est
fournie (littéralement ou via une variable), elle est affichée à la sortie, sinon un message d'erreur générique
est affiché. Ce mécanisme permet à l'auteur d'une fonction d'anticiper une erreur d'exécution ordinaire et/
ou de proposer un message d'erreur plus précis et utile. Par exemple,

si nelem(xlist) == 0
funcerr "xlist ne doit pas être vide" endif
Chapitre 14. Fonctions définies par l'utilisateur 120

Une fonction peut contenir plusieursretourdéclaration, comme dans

fonction scalaire multi (bool s)


si s
retour 1000
autre
retour dix
fin si
fonction de fin

Cependant, il est recommandé dans la pratique de programmation d'avoir un seul point de retour à partir d'une
fonction, sauf si cela est très gênant. L'exemple simple ci-dessus serait mieux écrit comme

fonction scalaire multi (bool s)


Retour ? 1000 : 10 fin de
fonction

Surcharge
Vous avez peut-être remarqué que plusieurs fonctions intégrées dans gretl sont "surchargées", c'est-à-dire qu'un
emplacement d'argument donné peut accepter plus d'un type d'argument et que la valeur de retour peut
dépendre du type d'argument en question. Par exemple, l'argumentXpour lepdf()La fonction peut être un
scalaire, une série ou une matrice et le type de retour correspondra à ce choix de la part de l'appelant.
Depuis gretl-2021b, cette possibilité existe également pour les fonctions définies par l'utilisateur. Le méta-typenumérique peut
être utilisé à la place d'un type spécifique pour accepter un argument scalaire, série ou matriciel, et de même le type de retour
d'une fonction peut être marqué commenumérique.

En tant qu'auteur de fonction, vous pouvez choisir d'être plus restrictif que la valeur par défaut (qui autorise
scalaire, série ou matrice pour toutnumériqueargument). Par exemple, si vous écrivez une fonction dans laquelle
deux arguments,Xety, sont spécifiés sous forme numérique, vous pouvez décider d'interdire le cas oùXest une
matrice etyune série, ou vice versa, comme trop compliqué. Vous pouvez utiliser leType de()fonction pour
déterminer quels types d'arguments ont été fournis, et lafuncerrcommande ouerreursi() fonction pour rejeter une
combinaison non prise en charge.
Si votre fonction va retourner un certain type spécifique (par exemple,matrice)quel que soit le type d'entrée, la
valeur de retour doit être étiquetée en conséquence : utiliseznumériquepour le retour seulement s'il est vraiment
inconnu à l'avance.
Référencement14.2offre un exemple (certes artificiel) : sonnumériqueles entrées peuvent être des scalaires, des séries ou des
vecteurs colonnes mais elles doivent être d'un seul type.

Naturellement, si votre fonction surchargée est destinée à un usage public, vous devez indiquer clairement dans sa
documentation ce qui est pris en charge et ce qui ne l'est pas.

Vérification des erreurs

Lorsque gretl lit et "compile" pour la première fois une définition de fonction, la vérification des erreurs est minimale : les
seules vérifications sont que le nom de la fonction est acceptable et, en ce qui concerne le corps, que vous n'essayez pas
de définir une fonction à l'intérieur d'un fonction (voir section14.1). Sinon, si le corps de la fonction contient des
commandes non valides, cela ne deviendra apparent que lorsque la fonction sera appelée et que ses commandes seront
exécutées.

Débogage
Le mécanisme habituel par lequel gretl renvoie les commandes et signale la création de nouvelles variables est
par défaut supprimé lors de l'exécution d'une fonction. Si vous souhaitez une sortie plus détaillée d'une fonction
particulière, vous pouvez utiliser l'une des commandes suivantes ou les deux dans la fonction :
Chapitre 14. Fonctions définies par l'utilisateur 121

Listing 14.2 :Exemple de fonction surchargée[Télécharger▼]

fonction numérique x_plus_b_y (numérique x, scalaire b, numérique y)


errorif(typeof(x) != typeof(y), "x et y doivent être du même type") if typeof(x) <= 2 # scalaire
ou série
retourner x + b*y
elif lignes(x) == lignes(y) && colonnes(x) == 1 && colonnes(y) == 1
retourner x + b*y
autre
funcerr "x et y doivent être des vecteurs colonnes" endif

fonction de fin

# call 1 : x et y sont des scalaires eval


x_plus_b_y(10, 3, 2)

# appel 2 : x et y sont des vecteurs


matrice x = mnormal(10, 1) matrice y =
mnormal(10, 1) eval x_plus_b_y(x, 2, y)

données ouvertes4-1
# appel 3 : x et y sont des séries
series bb = x_plus_b_y(bedrms, 0.5, baths) print bb --byobs

ensemble écho sur


ensemble message sur

Alternativement, vous pouvez obtenir cet effet pour toutes les fonctions via la commandedéfinir le débogage 1.Généralement,
lorsque vous définissez la valeur d'une variable d'état à l'aide de laensemblecommande, l'effet s'applique uniquement au niveau
actuel d'exécution de la fonction. Par exemple, si vous faitesactiver les messagesdans la fonctionf1, qui à son tour appelle la
fonctionf2,alors les messages seront imprimés pourf1mais nonf2.La variable de débogage, cependant, agit globalement ; toutes
les fonctions deviennent verbeuses quel que soit leur niveau.

De plus, vous pouvez fairedéfinir le débogage 2 :en plus de l'écho de la commande et de l'impression des
messages, cela équivaut à paramétrermax_verbeux (qui produit une sortie détaillée du maximiseur BFGS) à tous
les niveaux d'exécution de la fonction.

14.5 Packs de fonctions


À divers points ci-dessus, nous avons fait allusion aux packages de fonctions et à leur utilisation via l'interface graphique
gretl. Ce sujet est traité en profondeur par leGuide du paquet de fonctions Gretl. Si vous utilisez Gretl, vous pouvez le
trouver sous leAidermenu. Sinon, vous pouvez le télécharger à partir de

https://sourceforge.net/projects/gretl/files/manual/
Chapitre 15

Listes et chaînes nommées

15.1 Listes nommées

De nombreuses commandes gretl prennent une ou plusieurs listes de séries comme arguments. Pour rendre cela plus facile à
gérer dans le contexte des scripts de commande, et en particulier dans les fonctions définies par l'utilisateur, gretl offre la
possibilité delistes nommées.

Créer et modifier des listes nommées


Une liste nommée est créée à l'aide du mot-cléliste,suivi du nom de la liste, d'un signe égal et d'une expression formant
une liste. Le type d'expression le plus basique qui fonctionne dans ce contexte est une liste de variables séparées par des
espaces, données soit par leur nom, soit par leur numéro d'identification. Par exemple,

liste xlist = 1 2 3 4 liste reglist =


revenu prix

Notez que les variables en question doivent être de type série. Deux

abréviations sont disponibles dans les listes de définition :

• Vous pouvez utiliser le caractère générique "*" pour créer une liste de variables par nom. Par exemple, dum*peut
être utilisé pour indiquer toutes les variables dont le nom commence pardum.

• Vous pouvez utiliser deux points pour indiquer une plage de variables. Par exemplerevenu..prixindique
l'ensemble des variables dont les numéros d'identification sont supérieurs ou égaux à celui derevenuet
inférieur ou égal à celui deprix.

De plus, il existe deux formulaires spéciaux :

• Si vous utilisez le mot clénulsur le côté droit, vous obtenez une liste vide.

• Si vous utilisez le mot clébase de donnéesà droite, vous obtenez une liste contenant toutes les séries du jeu de
données actuel (sauf les séries prédéfiniesconst).

Le nom de la liste doit commencer par une lettre et doit être composé uniquement de lettres, de chiffres ou du caractère
de soulignement. La longueur maximale du nom est de 31 caractères ; les noms de liste ne peuvent pas contenir
d'espaces.

Une fois qu'une liste nommée a été créée, elle sera "mémorisée" pour la durée de la session gretl (sauf si vous la
supprimez) et peut être utilisée dans le contexte de n'importe quelle commande gretl où une liste de variables est
attendue. Un exemple simple est la spécification d'une liste de régresseurs :

liste xlist = x1 x2 x3 x4 ols y 0 xlist

Pour vous débarrasser d'une liste, vous utilisez la syntaxe suivante :

liste xlist supprimer

122
Chapitre 15. Listes et chaînes nommées 123

Faire attention:supprimer xlistsupprimera la série contenue dans la liste, cela implique donc une perte de
données (ce qui peut ne pas être ce que vous voulez). D'autre part,liste xlist supprimerva simplement "indéfinir" le
xlistidentifiant ; la série elle-même ne sera pas affectée.
De même, pour imprimer les noms des membres d'une liste, vous devez inverser la commande d'impression habituelle, comme dans

liste xlist impression

Si tu dis justeimprimer xlistla liste sera étendue et les valeurs de toutes les séries de membres seront
imprimées.
Les listes peuvent être modifiées de différentes manières. Pourredéfinirune liste existante, utilisez la même syntaxe que
pour créer une liste. Par exemple

liste xliste = 1 2 3 xliste =


456

Après la deuxième mission,xlistcontient uniquement les variables 4, 5 et 6.


Pourajouterouajouterdes variables à une liste existante, nous pouvons utiliser le fait qu'une liste nommée
remplace une liste "longue". Par exemple, nous pouvons faire

liste xlist = xlist 5 6 7 xlist = 9 10


xlist 11 12

Une autre option pour ajouter un terme (ou une liste) à une liste existante consiste à utiliser +=, comme dans

xlist += cpi

Pour supprimer une variable d'une liste, utilisez -= :

xlist -= cpi

Dans la plupart des contextes où les listes sont utilisées dans gretl, on s'attend à ce qu'elles ne contiennent aucun
élément dupliqué. Si vous formez une nouvelle liste par simple concaténation, comme dansliste L3 = L1 L2 (oùL1et L2
sont des listes existantes), il est possible que le résultat contienne des doublons. Pour vous en prémunir, vous pouvez
former une nouvelle liste comme l'union de deux listes existantes :

liste L3 = L1 || L2

Le résultat est une liste qui contient tous les membres deL1,ainsi que tous les membres deL2qui ne sont pas déjà dansL1.

Dans le même ordre d'idées, vous pouvez construire une nouvelle liste à l'intersection de deux listes existantes :

liste L3 = L1 && L2

IciL3contient tous les éléments qui sont présents dans les deuxL1etL2. Vous pouvez

également soustraire une liste d'une autre :

liste L3 = L1 - L2

Le résultat contient tous les éléments deL1qui ne sont pas présents dansL2. L'indexation

dans une liste définie est également possible, comme s'il s'agissait d'un vecteur :

liste L2 = L1[1:4]

Cela laisse L2 avec les quatre premiers membres deL1.Notez que l'ordre des membres de la liste dépend du
chemin.
Chapitre 15. Listes et chaînes nommées 124

Listes et matrices
Une autre façon de former une liste est par affectation à partir d'une matrice. La matrice en question doit être interprétable
comme un vecteur contenant des numéros d'identification de séries de données. Il peut s'agir d'un vecteur de ligne ou de
colonne, et chacun de ses éléments doit avoir une partie entière qui n'est pas supérieure au nombre de variables dans
l'ensemble de données. Par exemple:

matrice m = {1,2,3,4} liste L


=m

Ce qui précède est acceptable à condition que l'ensemble de données contienne au moins 4 variables.

Interroger une liste

Vous pouvez déterminer le nombre de variables ou d'éléments dans une liste à l'aide de la fonctionnelem().

liste xlist = 1 2 3 nl =
nelem(xlist)

La variable (scalaire)NLrecevra une valeur de 3 puisquexlistcontient 3 membres.


Vous pouvez déterminer si une série donnée est membre d'une liste spécifiée à l'aide de la fonction dans la liste(),
un péché

scalaire k = inlist(L, y)

oùLest une liste etyune série. La série peut être spécifiée par son nom ou son numéro d'identification. La valeur de retour
est la position (base 1) de la série dans la liste, ou zéro si la série n'est pas présente dans la liste.

Génération de listes de variables transformées

Étant donné une liste nommée de séries, vous pouvez générer des listes de transformations de ces séries à l'aide
des fonctionsjournal, décalages, diff, ldiff, sdiffousimuler.Par exemple

liste xlist = x1 x2 x3 liste lxlist =


log(xlist) liste difflist = diff(xlist)

Lors de la génération d'une liste dedécalagesde cette manière, vous spécifiez l'ordre de décalage maximal entre
parenthèses, avant le nom de la liste et séparé par une virgule. Par exemple

liste xlist = x1 x2 x3 liste laglist = lags(2,


xlist)

ou

ordre scalaire = 4
list laglist = lags(ordre, xlist)

Ces commandes remplirontlaglistavec le nombre spécifié de retards des variables dansxlist. Vous pouvez
donner le nom d'une seule série à la place d'une liste comme deuxième argument àdécalages :cela
équivaut à donner une liste avec un seul membre.
LesimulerLa fonction crée un ensemble de variables fictives codant pour toutes les valeurs distinctes prises par la
variable d'origine, sauf une, qui doit être discrète. (La plus petite valeur est considérée comme la catégorie
omise.) Comme les décalages, cette fonction renvoie une liste même si l'entrée est une seule série.
Chapitre 15. Listes et chaînes nommées 125

Une autre opération utile que vous pouvez effectuer avec les listes est la créationinteractionvariables. Supposons que
vous ayez une variable discrèteXje, en prenant des valeurs de 1 ànet une variablezje, qui peut être continue ou discrète.
Dans de nombreux cas, vous souhaitez "diviser"zjedans un ensemble denvariables via la règle
{
z(j) zje quandXje= j
je =
0 sinon;

en pratique, vous créez des mannequins pourXjevariable d'abord, puis vous les multipliez tous parzje; ceux-ci sont
communément appelés lesinteractionsentreXjeetzje. En gret tu peux faire

liste H = D ^ Z

oùDest une liste de séries discrètes (ou une seule série discrète),Zest une liste (ou une seule série)1; toutes
les interactions seront créées et listées ensemble sous le nomH
Un exemple est fourni dans le script15.1

Génération de séries à partir de listes

Il existe différentes manières de récupérer ou de générer des séries individuelles à partir d'une liste nommée. La méthode la plus
basique consiste à indexer dans la liste. Par exemple,

série x3 = Xlist[3]

récupérera le troisième élément de la listeXlistsous le nomx3 (ou générera une erreur si Xlistcompte moins
de trois membres).
De plus, gretl propose plusieurs fonctions qui s'appliquent à une liste et renvoient une série. Dans la plupart des cas, ces fonctions
s'appliquent également à des séries uniques et se comportent comme des extensions naturelles lorsqu'elles sont appliquées à des listes,
mais ce n'est pas toujours le cas.

Pour reconnaître et gérer les valeurs manquantes, gretl propose plusieurs fonctions (voir leRéférence des commandes
Gretlpour plus de détails). Dans ce contexte, il convient de remarquer que led'accord()La fonction peut être utilisée avec
un argument de liste. Par exemple,

liste xlist = x1 x2 x3 série xok =


ok(xlist)

Après ces commandes, la sériexokaura la valeur 1 pour les observations où aucune desx1, x2,ou x3a une valeur
manquante et la valeur 0 pour toutes les observations où cette condition n'est pas remplie.
Les fonctionsmax, min, moyenne, sd, sommeetvarse comportent « horizontalement » plutôt que « verticalement »
lorsque leur argument est une liste. Par exemple, les commandes suivantes

liste Xlist = x1 x2 x3 série m =


moyenne(Xlist)

produire une sériemdontje-ème élément est la moyenne deX1,je,X2,jeetX3,je; les valeurs manquantes, le cas échéant, sont
implicitement ignorées.

De plus, gretl propose trois fonctions pour les opérations pondérées :wsignifie, wsdetwvar.Considérons à
titre indicatif le tableau15.1: les trois premières colonnes sont le PIB par habitant pour la France,
l'Allemagne et l'Italie ; les colonnes 4 à 6 contiennent la population de chaque pays. Si nous voulons calculer
un indicateur agrégé du PIB par habitant, il suffit de

liste Ypc = YpcFR YpcGE YpcIT liste N =


NFR NGE NIT
y = wmoyen(Ypc, N)

1Avertissement : cette construction nepastravailler si ni l'un ni l'autreDniZsont du type liste.


Chapitre 15. Listes et chaînes nommées 126

Liste 15.1 :Utilisation des listes d'interactions[Télécharger▼]


Saisir:

ouvrir mroz87.gdt --calme

# le codage ci-dessous fait en sorte que


# ENFANTS = 0 -> pas d'enfants
# KIDS = 1 -> jeunes enfants uniquement
# KIDS = 2 -> enfants jeunes ou plus âgés

série KIDS = (KL6 > 0) + ((KL6 > 0) || (K618 > 0))

liste D = CIT KIDS # interaction variables discrètes liste X = WE WA #


variables à "séparer"
liste INTER = D ^ X

petit 1 6

impression DX INTER -o

Sortie (parties sélectionnées) :

ICT ENFANTS NOUS Washington WE_CIT_0

1 0 2 12 32 12
2 1 1 12 30 0
3 0 2 12 35 12
4 0 1 12 34 12
5 1 2 14 31 0
6 1 0 12 54 0

WE_CIT_1 WA_CIT_0 WA_CIT_1 WE_KIDS_0 WE_KIDS_1

1 0 32 0 0 0
2 12 0 30 0 12
3 0 35 0 0 0
4 0 34 0 0 12
5 14 0 31 0 0
6 12 0 54 12 0

NOUS_ENFANTS_2 WA_KIDS_0 WA_KIDS_1 WA_KIDS_2

1 12 0 0 32
2 0 0 30 0
3 12 0 0 35
4 0 0 34 0
5 14 0 0 31
6 0 54 0 0

donc par exemple

114.9×59830.635+124.6×82034.771+119.3×56890.372
y1996= =120.163
59830.635+82034.771+56890.372

Voir leRéférence des commandes Gretlpour plus de détails.


Chapitre 15. Listes et chaînes nommées 127

YpcFR YpcGE YpcIT NFR NGE LENTE

1997 114,9 124,6 119.3 59830.635 82034.771 56890.372


1998 115,3 122,7 120.0 60046.709 82047.195 56906.744
1999 115,0 122.4 117.8 60348.255 82100.243 56916.317
2000 115,6 118,8 117.2 60750.876 82211.508 56942.108
2001 116,0 116,9 118.1 61181.560 82349.925 56977.217
2002 116,3 115,5 112.2 61615.562 82488.495 57157.406
2003 112,1 116,9 111.0 62041.798 82534.176 57604.658
2004 110,3 116.6 106.9 62444.707 82516.260 58175.310
2005 112,4 115.1 105.1 62818.185 82469.422 58607.043
2006 111,9 114.2 103.3 63195.457 82376.451 58941.499

Tableau 15.1 :PIB par habitant et population dans 3 pays européens (Source : Eurostat)

15.2 Chaînes nommées


Dans certains cas, il peut être utile d'enregistrer une chaîne (c'est-à-dire une séquence de caractères) en tant que variable
nommée pouvant être réutilisée.

Quelques exemples de la définition d'une variable de chaîne sont présentés ci-dessous.

string s1 = "quelques trucs que je veux sauvegarder"


string s2 = getenv("HOME")
chaîne s3 = s1 + 11

Le premier champ après le nom du typechaîneest le nom sous lequel la chaîne doit être enregistrée, puis
vient un signe égal, puis vient une spécification de la chaîne à enregistrer. Cela peut prendre l'une des
formes suivantes :

• un littéral de chaîne (entre guillemets doubles) ; ou

• le nom d'une variable de chaîne existante ; ou

• une fonction qui renvoie une chaîne (voir ci-dessous) ; ou

• l'un des éléments ci-dessus suivi de + et d'un décalage entier.

Le rôle du décalage d'entier est d'utiliser une sous-chaîne de l'élément précédent, en commençant au décalage de
caractère donné. Une chaîne vide est renvoyée si le décalage est supérieur à la longueur de la chaîne en question.

Pour ajouter à la fin d'une chaîne existante, vous pouvez utiliser l'opérateur ~=, comme dans

string s1 = "quelques trucs que je veux" string s1


~= "enregistrer"

ou vous pouvez utiliser l'opérateur ~ pour joindre deux ou plusieurs chaînes, comme dans

chaîne s1 = "doux"
string s2 = "Maison, " ~ s1 ~ " maison."

Notez que lorsque vous définissez une variable de chaîne à l'aide d'un littéral de chaîne, aucun caractère n'est traité comme
"spécial" (autre que les guillemets doubles qui délimitent la chaîne). Plus précisément, la barre oblique inverse n'est pas utilisée
comme caractère d'échappement. Ainsi, par exemple,
Chapitre 15. Listes et chaînes nommées 128

chaîne s = "\"

est une affectation valide, produisant une chaîne qui contient un seul caractère barre oblique inverse.

Si vous souhaitez utiliser des barres obliques inverses pour indiquer les retours à la ligne, les tabulations, les guillemets doubles
intégrés, etc., utilisez lesprintffonction à la place (voirprintfcommande pour un compte rendu des caractères d'échappement).
Cette fonction peut également être utilisée pour produire une variable de chaîne dont la définition implique les valeurs d'autres
variables, comme dans

scalaire x = 8
foo = sprintf("var%d", x) # produit "var8"

Variables de chaîne et substitution de chaîne

Les variables de chaîne peuvent être utilisées de deux manières dans les scripts : le nom de la variable peut être saisi « tel
quel », ou il peut être précédé du signe « arobase », @. Dans la première variante, la chaîne nommée est traitée comme
une variable à part entière, tandis que la seconde appelle une "substitution de chaîne". Le contexte détermine laquelle de
ces variantes est appropriée.

Dans les contextes suivants, les noms des variables de chaîne doivent être donnés en clair (sans le signe
"arobase") :

• Lorsqu'une telle variable apparaît parmi les arguments de laprintfcommande ousprintf fonction.

• Lorsqu'une telle variable est donnée comme argument à une fonction.

• Sur le côté droit d'unchaînemission.

Voici une illustration de l'utilisation d'un argument de chaîne nommé avecprintf :

? chaîne vstr = "variance" Chaîne


générée vstr
? printf "vstr : %12s\n", vstr vstr :
variance

La substitution de chaîne peut être utilisée dans des contextes où une variable de chaîne n'est pas acceptable en tant
que telle. Si gretl rencontre le symbole @ suivi directement du nom d'une variable chaîne, cette notation est traitée
comme une « macro » : la valeur de la variable est substituée littéralement dans la ligne de commande avant que
l'analyse régulière de la commande ne soit effectuée.

Une utilisation courante de la substitution de chaîne est lorsque vous souhaitez construire et utiliser le nom d'une série
par programmation. Par exemple, supposons que vous vouliez créer 10 séries normales aléatoires nomméesnorme1
pournorme10.Ceci peut être accompli comme suit.

chaîne sname = boucle


nulle i=1..10
sname = sprintf("norm%d", i) series
@sname = normal() endloop

Notez que plaineLe nom dene pouvait pas être utilisé dans la deuxième ligne de la boucle : l'effet serait de
tenter d'écraser la variable de chaîne nomméeLe nom deavec une série du même nom. Ce que nous
voulons, c'est pour le courantvaleurdeLe nom deêtre déversé directement dans la commande qui définit
une série, et la notation "@" y parvient.
Une autre utilisation typique de la substitution de chaîne est lorsque vous souhaitez que les options utilisées avec une
commande particulière varient en fonction de certaines conditions. Par exemple,
Chapitre 15. Listes et chaînes nommées 129

function void use_optstr (series y, list xlist, int verbose)


chaîne optstr = verbeux ? "" : "--simple-print" ols y xlist @optstr

fonction de fin

données ouvertes4-1
liste X = const sqft
use_optstr(prix, X, 1)
use_optstr(prix, X, 0)

Lors de l'impression de la valeur d'une variable de chaîne à l'aide de laimprimercommande, le nom de la variable en clair doit
généralement être utilisé, comme dans

string s = "Just testing" print s

La variante suivante est équivalente, quoique maladroite.

string s = "Just testing" print "@s"

Mais notez que cette variante suivante fait quelque chose de tout à fait différent.

string s = "Just testing" print @s

Après la substitution de chaîne, la commande d'impression lit

imprimer Je teste juste

qui tente d'imprimer les valeurs de deux variables,Justeetessai.

Chaînes intégrées

Outre les chaînes que l'utilisateur peut définir, certaines variables de chaîne sont définies par gretl lui-même. Ceux-ci peuvent
être utiles pour les personnes qui écrivent des fonctions qui incluent des commandes shell. Les chaînes intégrées sont comme
indiqué dans le tableau15.2.

gretldir le répertoire d'installation de gretl le répertoire de travail


workdir actuel de l'utilisateur de gretl le répertoire utilisé par gretl
pointdir pour les fichiers temporaires le chemin d'accès ou le nom du
gnuplot gnuplotchemin d'accès exécutable ou nom dutramochemin
tramo d'accès exécutable ou nom dux-12-arimaexécutable tramo
x12a répertoire de données
tramodir
x12adir x-12-arimarépertoire de données

Tableau 15.2 :Variables de chaîne intégrées

Pour y accéder en tant que variables de chaîne ordinaires, ajoutez un signe dollar (comme dans $pointdir);pour les utiliser en
mode de substitution de chaîne, ajoutez le signe arobase (@pointdir).

Lire des chaînes de l'environnement


Il est possible de lire dans les chaînes nommées de gretl des valeurs définies dans l'environnement externe. Pour
ce faire, vous utilisez la fonctionobtenir,qui prend le nom d'une variable d'environnement comme argument. Par
exemple:
Chapitre 15. Listes et chaînes nommées 130

? chaîne user = getenv("USER") Chaîne


générée utilisateur
? chaîne home = getenv("HOME") Chaîne
générée home
? printf "Le répertoire personnel de %s est %s\n", utilisateur, le
répertoire personnel de cottrell est /home/cottrell

Pour vérifier si vous avez obtenu une valeur non vide d'un appel donné àobtenir,vous pouvez utiliser la fonction
strlen,qui récupère la longueur de la chaîne, comme dans

? string temp = getenv("TEMP") Chaîne


générée temp
? scalaire x = strlen(temp) Scalaire
généré x = 0

Capturer des chaînes via le shell


Si les commandes shell sont activées dans gretl, vous pouvez capturer la sortie de ces commandes en utilisant la syntaxe

chaînenom de chaîne= $(commande shell)


Autrement dit, vous placez une commande shell entre parenthèses, précédée d'un signe dollar.

Lecture d'un fichier dans une chaîne

Vous pouvez lire le contenu d'un fichier dans une variable chaîne en utilisant la syntaxe

chaînenom de chaîne=lirefichier(nom de fichier)

Lenom de fichierchamp peut être donné sous la forme d'une variable de chaîne. Par exemple

? fname = sprintf("%s/QNC.rts", $x12adir) Chaîne


générée fname
? string foo = readfile(fname) Chaîne
générée foo

Plus de fonctions de chaîne

Gretl propose plusieurs fonctions pour créer ou manipuler des chaînes. Vous pouvez les trouver listés et
expliqués dans leRéférence des fonctionssous la catégorieCordes.
Chapitre 16

Série à valeur de chaîne

16.1 Présentation
Par série à valeur de chaîne, nous entendons une série dont les valeurs primaires sont des chaînes (bien qu'en
interne, ces séries comprennent un codage entier plus un mappage "dictionnaire" des valeurs entières aux
chaînes). Ce chapitre explique comment créer de telles séries et décrit les opérations qui sont prises en charge
pour elles.

16.2 Création d'une série de valeurs de chaîne

Cela peut se faire de trois manières :

• en lisant une telle série à partir d'un fichier source approprié ;

• en prenant une série numérique appropriée dans gretl et en ajoutant des valeurs de chaîne à l'aide de lachaîner()
fonction; et

• par affectation directe à une série à partir d'un tableau de chaînes.

Dans chaque cas, les valeurs de chaîne seront préservées lorsqu'une telle série est enregistrée dans un fichier de données natif gretl.

Lecture de séries de valeurs de chaîne

La principale "source appropriée" pour les séries à valeur de chaîne est un fichier de données texte délimité (mais
voir la section16.5dessous). Voici un petit exemple. Voici le contenu d'un fichier nommégc.csv :

ville, année
"Bilbao",2009
"Toruń",2011
"Oklahoma City", 2013
"Berlin",2015
"Athènes",2017
"Naples",2019

Un script pour lire ce fichier et sa sortie sont affichés dans la liste16.1, à partir de laquelle nous pouvons voir quelques
choses.

• Par défaut leimprimerla commande nous montre les valeurs de chaîne de la sérieville,et il gère les caractères non-
ASCII à condition qu'ils soient en UTF-8 (mais il ne gère pas les chaînes plus longues de manière très élégante).

• Le --numériquepossibilité deimprimerexpose les codes entiers pour une série de valeurs de chaîne.

• La syntaxenom de la série[obs]renvoie une chaîne lorsqu'une série a une valeur de chaîne.

Supposons que vous vouliez accéder au code numérique d'une observation à valeur de chaîne particulière : vous pouvez
l'obtenir en "convertissant" la série en un vecteur. Ainsi

131
Chapitre 16. Séries de chaînes 132

Liste 16.1 :Utilisation d'une série de valeurs de chaîne


Saisir:

ouvrir gc.csv --calme


imprimer - - byobs
imprimer la ville --byobs --numeric
printf "La troisième conférence gretl a eu lieu à %s.\n", city[3]

Sortir:

? imprimer - - byobs

ville année

1 Bilbao 2009
2 Courir 2011
3 Oklahoma C.. 2013
4 Berlin 2015
5 Athènes 2017
6 Naples 2019

? imprimer la ville --byobs --numeric

ville

1 1
2 2
3 3
4 4
5 5
6 6

La troisième conférence Gretl a eu lieu à Oklahoma City.


Chapitre 16. Séries de chaînes 133

printf "Le code pour '%s' est %d.\n", ville[3], {ville}[3]

donne

Le code pour 'Oklahoma City' est 3.

Les codes numériques des séries à valeur de chaîne sont toujours affectés ainsi : en lisant le fichier de données ligne par ligne, la
première valeur de chaîne est affectée de 1, la suivantedistinctla valeur de chaîne est affectée de 2, et ainsi de suite.

Affectation de valeurs de chaîne à une série existante

Cela se fait via lechaîner()fonction, qui prend deux arguments, le nom d'une série et un tableau de chaînes.
Pour que cela fonctionne, deux conditions doivent être remplies :

1. La série ne doit contenir que des valeurs entières et la plus petite valeur doit être supérieure ou égale à 1.

2. Le tableau de chaînes doit avoir au moinsnmembres distincts, oùnest la plus grande valeur trouvée
dans la série.

La logique de ces conditions est que nous cherchons à créer un mappage comme décrit ci-dessus, à partir d'une
séquence d'entiers de base 1 vers un ensemble de chaînes. Cependant, nous admettons la possibilité que la série
en question soit un échantillon incomplet d'une population associée. Supposons que nous ayons une série qui va
de 2, 3, 5, 9, 10. Ceci est considéré comme un échantillon d'une population qui a au moins 10 valeurs discrètes, 1,
2, . . . , 10, et nécessite donc au moins 10 chaînes de valeur.
Voici (une version simplifiée) d'un exemple que l'un des auteurs a eu raison d'utiliser : dériver des « notes alphabétiques
» de style américain à partir d'une série contenant des scores en pourcentage pour les étudiants. Appelez la série de
pourcentageX, et disons que nous voulons créer une série avec des valeursUNpourX≥90,Bpour 80≤x <90, et ainsi de suite
jusqu'àFpourx <60. Alors on peut faire :

note de série = 1 # F, la note la plus faible += x >=


60 # D
grade += x >= 70 # grade C += x >= 80 # grade B += x
>= 90 # A stringify(grade, strsplit("FDCB A"))

La façon dont legradeLa série est construite n'est pas la plus compacte, mais elle est agréable et explicite,
et facile à modifier si l'on veut ajuster les valeurs de seuil. Notez l'utilisation destrsplit()pour créer un
tableau de chaînes à la volée à partir d'un littéral de chaîne ; c'est pratique lorsque le tableau contient un
nombre modéré d'éléments sans espaces intégrés. Une autre façon d'obtenir le même résultat est de
définir le tableau de chaînes via ledefarray()fonction, comme dans

stringify(grade,defarray("F","D","C","B","A"))

L'opération inverse dechaîner()peut être effectué par lestrvals()fonction : cela récupère le tableau de valeurs
de chaîne distinctes d'une série (ou renvoie un tableau vide si la série n'a pas de valeur de chaîne).

Affectation à partir d'un tableau de chaînes

Étant donné un tableau de chaînes dont la longueur correspond soit à la longueur totale de l'ensemble de données actuel, soit à
la longueur de la plage d'échantillons actuelle, vous pouvez affecter directement un résultat de série. Voici un exemple trivial :
Chapitre 16. Séries de chaînes 134

nulldata 6
chaînes S = defarray("a", "b", "c", "b", "a", "d") série sx = S

imprimer sx --byobs

Voici un deuxième exemple où nous créons une série de valeurs de chaîne en utilisant les "marqueurs d'observation" de
l'ensemble de données actuel, après les avoir saisis sous forme de tableau via leMarqueurscommande:

données ouvertes4-10
marqueurs --to-array=S
état de la série = S état
d'impression --byobs

Et voici un troisième exemple où nous construisons le tableau de chaînes en lisant à partir d'un fichier texte :

nulldata 8
série sv = strsplit(readfile("ABCD.txt")) print sv --byobs

Cela fonctionnera bien si le contenu deABCD.txtest quelque chose comme

ABCDDCBA

(contenant 8 valeurs séparées par des espaces, avec ou sans saut de ligne). Si les chaînes en question
contiennent des espaces intégrés, vous devrez utiliser le deuxième argument facultatif pourstrsplit.

16.3 Opérations autorisées


Une question qui se pose avec les séries à valeur de chaîne est la suivante : qu'êtes-vous autorisé à en faire et
qu'est-ce qui est interdit ? La politique optimale peut être discutable, mais nous présentons ici l'état actuel des
choses.

Réglage des valeurs par observation

Vous pouvez définir des valeurs particulières dans une série de valeurs de chaîne soit par chaîne soit par code numérique. Par
exemple, supposons (par rapport à l'exemple de la section16.2) que, pour une raison quelconque, l'élève numéro 31 avec un
pourcentage de 88 mérite néanmoins uneUNgrade. Nous pourrions faire

note[31] = "A"

ou, si nous sommes sûrs du mappage,

note[31] = 5

Ou pour augmenter la note de l'élève d'une lettre :

note[31] += 1

Ce que tu espasautorisé à faire ici est de faire un ajustement numérique qui mettrait la valeur hors limites par
rapport à l'ensemble de valeurs de chaîne. Par exemple, si nous essayonsnote[31] = 6nous obtiendrions une
erreur.
D'autre part, vouspeutétend implicitement l'ensemble des valeurs de chaîne. Cela n'aurait pas de sens pour l'exemple des notes
alphabétiques, mais cela pourrait être le cas, par exemple, pour les noms de ville. Revenant à l'exemple de la section16.2 supposons que
nous essayons
Chapitre 16. Séries de chaînes 135

base de données addobs 1


année 7] = 2021
ville[7] = "Londres?"

Cela fonctionnera : nous ajoutons implicitement un autre membre à la table de chaînes pourville;le code
numérique associé sera le prochain entier disponible.1

Produit logique de deux séries à valeur de chaîne

L'opérateur ^ peut être utilisé pour produire ce que nous pourrions appeler le produit logique de deux séries à valeur de chaîne, comme
dans

série sv3 = sv1 ^ sv2

Le résultat est une autre série à valeur de chaîne avec la valeursje.sjà des observations oùsv1a de la valeursje
etsv2a de la valeursj. Par exemple, si à une observation donnéesv1a de la valeur »UN"etsv2a de la valeur "X",alors
sv3aura de la valeur »HACHE".L'ensemble de chaînes attachées à la série résultante inclura toutes ces
combinaisons de chaînes même si elles ne sont pas toutes représentées dans l'échantillon donné.

Affectation à une série entière


À l'exception des cas "affectation à partir d'un tableau de chaînes" et "produit logique" décrits ci-dessus, cela est
actuellement interdit : vous ne pouvez pas exécuter une affectation avec le nom d'une série de valeurs de chaîne. en soi
sur la gauche. En d'autres termes, vous ne pouvez pas écraser une série entière de valeurs de chaîne à la fois. Bien que
cela soit discutable, c'est le moyen le plus simple de s'assurer que nous ne nous retrouvons jamais avec une cartographie
cassée. Il est possible que cette restriction soit assouplie à l'avenir.

Outre l'attribution d'une valeur numérique hors limites à une observation particulière, ce type d'attribution
est en fait la seule opération interdite pour les séries à valeurs de chaîne.

Valeurs manquantes

Nous prenons en charge une exception à la règle générale, ne rompez jamais le mappage entre les chaînes et les codes numériques pour
les séries à valeur de chaîne : vous pouvez marquer des observations particulières comme manquantes. Cela se fait de la manière
habituelle, par exemple,

note[31] = NA

Notez cependant que lors de l'importation d'une série de chaînes à partir d'un fichier texte délimité, toutes les chaînes non vides
(y compris "NA") seront interprétées comme des valeurs valides ; toute valeur manquante dans un tel fichier doit donc être
représentée par des cellules vides.

Copie d'une série de valeurs de chaîne

Si vous faites une copie d'une série de valeurs de chaîne, comme dans

série foo = ville

les valeurs de chaîne sontpascopié par-dessus : vous obtenez une série purement numérique contenant les codes de la série
originale. Mais si vous voulez une copie complète avec les valeurs de chaîne qui peuvent facilement être organisées :

series citycopy = city stringify(citycopy,


strvals(city))

1Certes, il y a un inconvénient à cette fonctionnalité : on peut ajouter par inadvertance une nouvelle valeur de chaîne en tapant mal une chaîne
déjà présente.
Chapitre 16. Séries de chaînes 136

Série à valeur de chaîne dans d'autres contextes

Les séries à valeur de chaîne peuvent être utilisées à volonté sur le côté droit des instructions d'affectation, et dans ce
contexte, leurs valeurs numériques sont prises. Par exemple,

série y = sqrt(ville)

ne suscitera aucune plainte et générera une série numérique 1, 1.41421, . . . . C'est à l'utilisateur de juger si
ce genre de chose a un sens.
De même, c'est à l'utilisateur de décider s'il est logique d'utiliser une série à valeur de chaîne « telle quelle » dans un
modèle de régression, que ce soit en tant que régressand ou régresseur. Là encore, les valeurs numériques de la série
sont prises. Souvent, cela n'a pas de sens, mais parfois cela peut : les valeurs numériques peuvent, par conception,
former une échelle ordinale, voire cardinale (comme dans l'exemple de « note » de la section16.2).

Plus probablement, on voudrait utilisersimulersur une série de valeurs de chaîne avant de l'utiliser dans la modélisation
statistique. Dans ce contexte, les étiquettes de série de Gretl sont convenablement informatives. Par exemple,
supposons que nous ayons une sériecourseavec les valeurs numériques 1, 2 et 3 et les chaînes associées "Blanc", "Noir"
et "Autre". Puis le code hansl

liste D = dummify(race)
étiquettes

affichera ces étiquettes :

Drace_2 : mannequin pour race = 'Noir'


Drace_3 : mannequin pour race = 'Autre'

Étant donné une telle série, vous pouvez utiliser des valeurs de chaîne dans un exemple de restriction, comme dans

smpl race == "Noir" --restrict

(bien quecourse == 2serait également acceptable).

Accéder aux valeurs de chaîne

Nous avons mentionné ci-dessus deux manières d'accéder aux valeurs de chaîne d'une série donnée : via la syntaxe

nom de la série[obs]

pour obtenir une seule telle valeur ; et via lestrvals()fonction pour obtenir un tableau contenant toutes ses valeurs
distinctes. Nous notons ici une troisième option : affectation directe d'une série de chaînes à un tableau de
chaînes, comme dans

chaînes S = sv

oùsvest une série appropriée. Dans ce cas, vous obtenez un tableau contenanttouslesvchaînes pour les observations dans la
plage d'échantillons actuelle, pas seulement les valeurs distinctes comme avecefforts.

16.4 Séries et fonctions à valeur de chaîne


Les fonctions hansl définies par l'utilisateur peuvent traiter des séries de chaînes, bien qu'il y ait quelques points à noter.

Si vous fournissez une telle série comme argument à une fonction hansl, ses valeurs de chaîne seront accessibles
dans la fonction. On peut tester si une série donnéeargumentest une chaîne comme suit :
Chapitre 16. Séries de chaînes 137

si nelem(strvals(arg)) > 0
# Oui
autre
# Non
fin si

Supposons maintenant que l'on veuille mettre quelque chose comme le code qui a généré legradesérie dans la section
16.2dans une fonction. Cela peut être fait, maispassous la forme d'une fonction qui renvoie directement la série
souhaitée, c'est-à-dire quelque chose comme

série de fonctions letter_grade (série x)


qualité de série
# définir la note en fonction de x et la chaîner, comme indiqué ci-dessus,
renvoyer la note
fonction de fin

Malheureusement, ce qui précède serapastravail : l'appelant recevra legradesérie OK mais elle ne sera pas valorisée. À
première vue, cela peut sembler être un bogue, mais c'est défendable en raison de la façon dont les séries fonctionnent
dans gretl.

Le fait est que les séries ont, pour ainsi dire, deux degrés d'existence. Ils peuvent exister en tant que membres à part entière d'un
ensemble de données, ou ils peuvent avoir une existence éphémère en tant que tableaux simplement anonymes de nombres qui ont la
même longueur que les séries d'ensembles de données. Considérez la déclaration

série rootx1 = sqrt(x+1)

Sur le côté droit, nous avons la "série"x+1,qui est appelée à exister dans le cadre d'un calcul mais n'a pas de
nom et ne peut pas avoir de valeurs de chaîne. De même, considérez

note de la série = letter_grade(x)

La valeur de retour declassement par lettre()est également un tableau anonyme,2incapable de contenir des
valeurs de chaînejusqu'àil est affecté à la série nomméegrade.La solution consiste à définirgradeen série, au
niveau de l'appelant, avant d'appelerclassement par lettre(),un péché

function void letter_grade (série x, série *grade)


# définir la note en fonction de x et la stringifier
# cette version fonctionnera !
fonction de fin

# votre interlocuteur

...
qualité de série
letter_grade(x, &grade)

Comme vous le verrez dans le compte rendu ci-dessus, nous n'offrons pas de fonctionnalités très sophistiquées pour les séries à
valeur de chaîne. Nous les lirons à partir de sources appropriées et nous les créerons nativement viastringifier—et nous
essaierons de nous assurer qu'ils conservent leur intégrité, mais nous ne considérons pas, par exemple, la spécification d'une
série à valeurs de chaîne comme un régresseur comme une demande implicite d'inclure la dummification de ses valeurs
distinctes. Outre la paresse, cela reflète le fait que dans gretl une série à valeur de chaînepeutêtre utilisable « tel quel », selon la
façon dont il est défini ; vous pouvez utilisersimulersi tu en as besoin.

16.5 Autres formats d'importation

Dans la section16.2nous avons illustré la lecture de séries à valeur de chaîne en référence à un fichier de données texte
délimité. Gretl peut également gérer plusieurs autres sources de données à valeur de chaîne, y compris les formats de
feuille de calculxls, xlsx, gnumériqueetles coteset (dans une certaine mesure) les formats deStata, SASetSPSS.

2Une série nommée appropriée, avec des valeurs de chaîne, existait pendant l'exécution de la fonction, mais elle a cessé d'exister dès que la
fonction a été terminée.
Chapitre 16. Séries de chaînes 138

Fichiers statistiques

Stata prend en charge deux types de variables pertinentes : (1) celles qui sont de "type chaîne" et (2) les variables de l'un ou
l'autre type numérique qui ont des "étiquettes de valeur" définies. Ni l'un ni l'autre n'est exactement équivalent à ce que nous
appelons une "série à valeur de chaîne" dans gretl.

Les variables Stata de type chaîne n'ont pas de représentation numérique ; leurs valeurs sont littéralement des chaînes, et c'est
tout. Les variables numériques de Stata avec des étiquettes de valeur n'ont pas besoin d'être des valeurs entières et leur plus
petite valeur n'a pas besoin d'être 1 ; cependant, vous ne pouvez pas définir d'étiquette pour une valeur qui n'est pas un entier.
Ainsi, dans Stata, vous pouvez avoir une série qui comprend à la fois des valeurs entières et non entières, mais seules les valeurs
entières peuvent être étiquetées.3

Cela signifie que lors de l'importation dans gretl, nous pouvons facilement gérer les variables de type chaîne à partir de Statadonnées des
dossiers. Nous leur donnons un codage numérique de base 1 ; ceci est arbitraire mais ne contredit aucune information dans ledonnées
déposer. D'autre part, en général, nous ne sommes pas en mesure de gérer les variables numériques de Stata avec des étiquettes de
valeur ; actuellement, nous signalons les étiquettes de valeur à l'utilisateur mais n'essayons pas de les stocker dans l'ensemble de
données gretl. Nous pourrions vérifier ces variables et les importer en tant que séries à valeur de chaîne si elles satisfont aux critères
énoncés dans la section16.2mais nous ne le faisons pas actuellement.

Fichiers SAS et SPSS


Gretl est capable de lire et de conserver les valeurs de chaîne associées aux variables de SAS "export" (xpt)
fichiers, et aussi de SPSSsavdes dossiers. Ces variables semblent être sur le même modèle que les variables Stata
de type chaîne.

3Vérifié dans Stata 12.

Vous aimerez peut-être aussi