Dans le champ contemporain de l’analyse computationnelle des données et de la psychométrie quantitative, la transition fluide entre observations qualitatives et représentations numériques constitue la clé de voûte de toute inférence statistique rigoureuse. L’environnement de programmation statistique R, conçu initialement autour de paradigmes orientés données par Ross Ihaka et Robert Gentleman, propose une infrastructure sophistiquée pour la manipulation de structures discrètes. Toutefois, la conversion d’attributs catégoriels vers des formats quantitatifs matriciels présente de nombreux pièges conceptuels et informatiques qui menacent la validité interne des recherches empiriques lorsque les mécanismes sous-jacents demeurent méconnus des praticiens.
L’acte de numériser une variable catégorielle ne se résume pas à une banale substitution typologique au sein d’une structure de données. Il engage directement la légitimité théorique des opérations algébriques ultérieures, qu’il s’agisse du calcul d’une simple variance, de l’estimation des coefficients d’une régression logistique, ou de la décomposition en valeurs singulières dans le cadre d’un modèle d’équations structurelles. Entre la gestion opaque des pointeurs entiers assignés aux facteurs et la perte potentielle de sémantique lors de transformations vectorisées non contrôlées, les analystes doivent naviguer entre les exigences de l’algèbre computationnelle et la fidélité épistémologique des mesures comportementales.
Cet article propose un examen exhaustif et systématique des méthodes, des implications mathématiques et des protocoles computationnels permettant de convertir des variables catégorielles en formats numériques au sein de l’écosystème R. À travers l’analyse détaillée des structures de bas niveau du langage, de la comparaison critique des primitives de base, de l’exploration des grammaires modernes du Tidyverse et de l’étude de cas concrets en sciences cognitives, ce guide vise à doter les chercheurs et scientifiques de données d’un cadre méthodologique robuste garantissant une reproductibilité sans faille de leurs flux de traitement.
1. Introduction et fondements conceptuels des variables catégorielles en psychométrie
1.1 Typologie des échelles de mesure selon Stevens
L’évaluation quantitative des phénomènes psychologiques et comportementaux repose historiquement sur la formalisation théorique proposée par le psychologue Stanley Smith Stevens dans son article fondateur de 1946. Stevens a structuré la théorie de la mesure autour de quatre échelles fondamentales : nominale, ordinale, d’intervalles et de rapports. L’échelle nominale représente le niveau le plus élémentaire, où les nombres ou symboles n’ont d’autre fonction que de servir d’étiquettes identificatrices mutuellement exclusives et exhaustivement exhaustives. Aucune relation d’ordre ni aucune métrique de distance ne peut être déduite de ces assignations arbitraires. Par exemple, assigner la modalité 1 au phénotype témoin et la modalité 2 au groupe expérimental n’implique aucune supériorité arithmétique ou quantitative.
L’échelle ordinale introduit quant à elle une relation de transitivité et de hiérarchie entre les observations, sans toutefois garantir que l’intervalle séparant deux rangs consécutifs soit constant le long du continuum psychologique sous-jacent. Les inventaires de personnalité ou les questionnaires d’évaluation de la symptomatologie clinique reposent quasi exclusivement sur ce formalisme. Les échelles d’intervalles et de rapports confèrent une signification métrique aux écarts observés, ces dernières possédant en sus un zéro absolu non arbitraire autorisant le calcul de ratios géométriques.
Les implications de cette taxonomie sur les inférences statistiques sont majeures. L’application prématurée ou mécanique d’opérateurs arithmétiques tels que l’addition ou la multiplication sur des variables nominales transformées numériquement engendre des artefacts analytiques considérables, connus sous le nom d’erreurs de catégorie. Dès lors, la quantification des attributs qualitatifs ne constitue pas une fin en soi, mais un impératif technique pour adapter les données aux contraintes des algorithmes matriciels, requérant une vigilance constante quant au niveau de mesure réellement exploité.
1.2 Représentation des données catégorielles dans l’environnement R
Au sein du langage R, l’abstraction logicielle dédiée à la gestion des grandeurs qualitatives est le type factor. Contrairement aux intuitions communes des utilisateurs novices qui appréhendent les facteurs comme des vecteurs de chaînes de caractères enrichis, la structure interne de R emploie un schéma de double encodage particulièrement économe en mémoire vive. Un facteur est stocké sous la forme d’un vecteur atomique d’entiers discrets de 32 bits (type integer), auquel est adjoint un attribut de classe spécifique nommé factor ainsi qu’un attribut de métadonnées désigné par levels.
Ce vecteur d’attributs de niveaux contient les étiquettes textuelles uniques correspondant à chaque modalité observée ou théorique de la variable. La valeur numérique entière conservée en mémoire vive ne sert que d’indice de position pointant vers ce dictionnaire de chaînes de caractères. Ainsi, le premier niveau correspond à l’entier 1, le second à l’entier 2, et ainsi de suite suivant un ordonnancement prédéfini ou implicitement alphabétique.
Cette architecture engendre régulièrement des problématiques de compatibilité et de rétrocompatibilité, particulièrement lors de l’importation de jeux de données où les vecteurs textuels purs de type character se voient convertis de façon transparente en facteurs, ou réciproquement, sous l’effet d’options globales comme le tristement célèbre paramètre historique stringsAsFactors. Lorsque les fonctions de modélisation interagissent avec ces structures composites, les discordances entre le vecteur d’entiers sous-jacent et le vecteur textuel d’affichage constituent l’une des sources les plus prolifiques de bogues silencieux en programmation scientifique.
1.3 Objectifs de la transformation numérique en recherche comportementale
La conversion systématique et contrôlée des variables catégorielles en vecteurs numériques constitue une phase critique du pré-traitement des données en recherche comportementale et neuroscientifique. La première justification émane des exigences mathématiques fondamentales de l’algèbre linéaire, socle de la quasi-totalité des modèles multivariés. Les algorithmes d’analyse factorielle exploratoire (AFE), de modélisation par équations structurelles (SEM) et de régressions linéaires multiples requièrent des matrices d’entrées réelles pour décomposer les matrices de variance-covariance et procéder aux inversions matricielles requises par l’estimation du maximum de vraisemblance.
De surcroît, les bibliothèques contemporaines d’apprentissage automatique, telles que celles dédiées à l’optimisation par descente de gradient stochastique ou aux machines à vecteurs de support, refusent catégoriquement les objets non numériques en entrée. La conformité algorithmique exige donc une conversion explicite, transparente et totalement déterministe.
Enfin, dans le domaine des inventaires psychométriques, le calcul de scores composites additifs, l’évaluation de la consistance interne via le coefficient alpha de Cronbach ou l’oméga de McDonald exigent l’agrégation de réponses ordonnées préalablement traduites en valeurs scalaires. Il est impératif d’opérer cette transformation sans dénaturer la structure sous-jacente des données ni biaiser l’espacement latent entre les alternatives de réponse.
2. Architecture interne des facteurs en langage R
2.1 Mécanisme de codage sous-jacent des facteurs
Pour comprendre les nuances des opérations de conversion numérique, il convient de disséquer le fonctionnement bas niveau du noyau de R lors de la création d’un facteur. Lorsque la fonction factor() est invoquée sur un vecteur source, R procède à une analyse d’unicité sur les éléments entrants afin d’extraire la liste des modalités distinctes. Par défaut, si aucun vecteur d’ordonnancement explicite n’est transmis via l’argument levels, le moteur applique un tri lexicographique strict sur ces modalités pour définir l’ordre d’attribution des indices numériques.
Dès lors que cet ensemble de référence est fixé, R alloue un espace mémoire pour stocker un vecteur d’entiers de même longueur que le vecteur source. Chaque chaîne textuelle d’origine est alors remplacée par l’entier correspondant à sa position ordinale au sein du vecteur d’attribut levels. Il existe ainsi une dissociation structurelle totale entre l’étiquette sémantique affichée à l’écran lors d’un appel à la fonction d’impression et l’entité binaire résidant dans la mémoire de l’ordinateur.
Ce mécanisme comporte un risque majeur : l’ordre alphabétique implicite induit une distribution d’indices numériques qui ne reflète aucunement la dynamique naturelle du phénomène étudié. Par exemple, si une échelle ordinale comporte les modalités « Faible », « Moyen » et « Élevé », l’assignation alphabétique automatique attribuera l’indice 1 à « Élevé », l’indice 2 à « Faible » et l’indice 3 à « Moyen ». Une conversion numérique directe et non contrôlée inverserait et désorganiserait totalement la trajectoire sémantique de l’instrument de mesure.
2.2 Inspection critique des attributs d’un facteur
Avant d’engager la moindre transformation de type, l’analyste se doit de mener une inspection méticuleuse de la structure de l’objet manipulé. R met à disposition une panoplie de primitives destinées à sonder les métadonnées logicielles greffées sur le vecteur sous-jacent. L’appel à la fonction attributes() sur un facteur permet de dévoiler l’intégralité de son dictionnaire d’enregistrement, révélant simultanément le tableau des niveaux d’affichage et l’identifiant de classe S3.
L’utilisation couplée de class() et de levels() offre un diagnostic rapide de l’état de la variable. La fonction class() confirme la nature catégorielle en renvoyant la chaîne « factor », tandis que levels() renvoie un vecteur de caractères énumérant les modalités dans leur séquence indicielle exacte. La détection de métadonnées d’ordre explicites s’effectue via le prédicat is.ordered(), lequel renvoie une valeur booléenne indiquant si le facteur implémente formellement une hiérarchie scalaire reconnue par le système de typage de R.
Cette étape de diagnostic technique s’avère indispensable pour déceler les anomalies fréquentes issues de la collecte des données expérimentales. Parmi celles-ci figurent la présence d’espaces typographiques invisibles créant des niveaux doublons, des fautes d’orthographe générant des modalités orphelines, ou une troncature accidentelle de l’attribut de niveaux lors d’une concaténation vectorielle non supervisée.
3. Méthode fondamentale 1 : Conversion d’une variable unique via unclass()
3.1 Principe de décomposition structurelle avec unclass()
La fonction primitive unclass() constitue l’outil le plus direct et épuré pour accéder au cœur d’un facteur en R. Sur le plan de la théorie des objets au sein du système S3, unclass() agit en supprimant simplement l’attribut formel class associé à l’entité logicielle, sans toucher aux autres attributs de données. En dépouillant le facteur de son étiquette de classe, le moteur d’évaluation de R cesse d’intercepter les appels via les méthodes spécifiques aux facteurs et traite désormais l’objet sous sa forme élémentaire, à savoir un vecteur atomique d’entiers.
D’un point de vue computationnel, l’exécution de l’expression df$variable <- unclass(df$variable) sur une colonne spécifique d’un tableau de données présente une efficacité algorithmique remarquable. Contrairement aux fonctions de conversion de haut niveau qui allouent de nouveaux espaces mémoires et effectuent des copies profondes après vérification de types complexes, unclass() contourne les mécanismes de polymorphisme et préserve l’adresse mémoire du vecteur sous-jacent lorsque le ramasse-miettes le permet.
Néanmoins, la suppression de l’attribut de classe laisse souvent subsister l’attribut levels attaché au vecteur d’entiers résultant, ce qui peut occasionner des avertissements ultérieurs lors de transferts vers des formats matriciels stricts. Il est dès lors fréquent d’encapsuler cette approche dans une logique d’assignation explicite afin de garantir un nettoyage complet des métadonnées orphelines.
3.2 Application guidée sur une variable expérimentale unique
Pour concrétiser cette mécanique opérationnelle, considérons un protocole de recherche en psychologie cognitive évaluant les effets de divers paradigmes d’interférence attentionnelle sur les temps de réaction. Les sujets sont assignés de façon aléatoire à l’un des trois groupes expérimentaux suivants : « Contrôle », « Interférence Auditive » et « Interférence Visuelle ». Au sein du bloc de données de l’expérience, la variable identifiant cette appartenance est initialement enregistrée sous la forme d’un facteur nommé groupe.
Pour transformer cette colonne en un format numérique prêt pour l’intégration dans des routines mathématiques personnalisées, l’analyste exécute l’instruction de réassignation directe en ciblant le champ ciblé : df$groupe <- unclass(df$groupe). Suite à cette commande, la vérification empirique par l’intermédiaire de la primitive typeof(df$groupe) retourne immédiatement le type « integer », confirmant la métamorphose de l’attribut.
L’observation du vecteur transformé révèle que chaque occurrence du groupe « Contrôle » est désormais représentée par la valeur scalaire 1, tandis que les conditions « Interférence Auditive » et « Interférence Visuelle » ont reçu respectivement les valeurs 2 et 3, sous réserve que l’ordonnancement initial des niveaux ait été calibré de manière rigoureuse lors de l’instanciation initiale de la structure de données expérimentale.
3.3 Conséquences sur l’interprétation des indices numériques
Bien que l’exécution de unclass() résolve l’exigence d’une conversion computationnelle immédiate, elle génère une rupture sémantique définitive en occultant les libellés textuels originaux au profit d’indices entiers abstraits. Dans le cadre d’une publication scientifique ou d’un flux d’analyse partagé, une telle occultation expose l’équipe de recherche à des erreurs d’interprétation catastrophiques au moment de rendre compte des directions d’effets ou des coefficients de contraste.
Il est donc méthodologiquement impératif d’édifier un dictionnaire de codage méticuleusement documenté au moment précis où la transformation est opérée. Ce livre de codes doit associer sans ambiguïté chaque entier généré à la modalité phénoménologique d’origine. Sans cette précaution, toute tentative de réplication ultérieure par un tiers se heurtera à une indétermination interprétative quant à la signification concrète des valeurs 1, 2 ou 3.
En outre, en cas de réplication de l’étude avec un échantillon où l’une des modalités théoriques n’aurait pas été observée, une conversion par unclass() sur le nouveau jeu de données pourrait réattribuer les indices différemment si les niveaux n’avaient pas été déclarés de manière fixe et globale, brisant l’interopérabilité des scripts analytiques.
4. Méthode 2 : Traitement vectorisé de plusieurs variables catégorielles via sapply()
4.1 Formulation de la conversion multi-colonnes
Dans les contextes de recherche où les instruments de mesure administrent de vastes batteries de tests comprenant des dizaines de questions catégorielles, procéder à une conversion séquentielle colonne par colonne s’avère rédhibitoire et source de duplications de code propices aux erreurs. Le paradigme fonctionnel de R permet de répondre à cette problématique par l’intermédiaire de la fonction vectorisée sapply(), qui automatise l’application d’un opérateur sur des sous-ensembles matriciels sans nécessiter l’écriture d’itérations explicites.
La formulation canonique de cette approche repose sur un découpage préalable du tableau de données. L’analyste isole les variables qualitatives cibles par une indexation vectorielle ciblée, par exemple en formulant df[, c(« item1 », « item2 », « item3 »)], puis applique l’opérateur de décomposition structurelle au travers de l’instruction sapply(df[, c(« item1 », « item2 », « item3 »)], unclass). Les colonnes ainsi traitées sont immédiatement réassignées au sous-ensemble matriciel d’origine.
Cette approche garantit que les variables non sélectionnées, telles que les identifiants continus des participants ou les mesures chronométriques brutes, demeurent parfaitement intactes au sein du bloc de données principal, évitant ainsi toute altération globale intempestive du schéma relationnel du tableau d’analyse.
4.2 Avantages computationnels de la vectorisation
Sur le plan de l’optimisation des flux de traitement, l’élimination des boucles for écrites en langage interprété représente un bénéfice de premier ordre. Même si les versions contemporaines de R intègrent un compilateur à la volée (JIT) extrêmement performant qui atténue le surcoût historique des itérations explicites, la vectorisation via la famille des primitives apply transfère le coût de parcours des colonnes vers des routines écrites directement en langage C compilé.
Ce basculement algorithmique se traduit par un gain sensible de temps d’exécution lorsque les bases de données comportementales atteignent plusieurs dizaines de milliers d’observations réparties sur des centaines d’items. De surcroît, la transformation fonctionnelle applique une logique strictement identique et homogène à l’ensemble du sous-groupe de variables désigné, réduisant le risque de divergences méthodologiques dans le typage des colonnes.
Un autre bénéfice direct concerne le maintien de la cohérence dimensionnelle. En opérant sur des colonnes de longueurs strictement identiques, l’assignation par bloc assure que la structure bidimensionnelle du tableau de données sous-jacent conserve sa géométrie sans introduire de valeurs non définies par inadvertance.
4.3 Exemple pratique sur une batterie de tests psychométriques
Illustrons la puissance de cette méthodologie à l’aide d’une enquête épidémiologique en santé comportementale comprenant des items sociodémographiques (comme le niveau d’instruction et la catégorie socio-professionnelle) ainsi que des items cliniques mesurant l’adhésion thérapeutique. Ces variables qualitatives sont regroupées au sein d’un vecteur d’étiquettes nommé variables_cliniques.
L’exécution de la commande df[variables_cliniques] <- sapply(df[variables_cliniques], unclass) produit une conversion simultanée de l’intégralité des items ciblés. À l’issue de cette transformation, un contrôle de validité mené via l’instruction all(sapply(df[variables_cliniques], is.numeric)) confirme que chaque colonne ciblée est désormais perçue par le système comme une grandeur numérique continue ou entière.
Toutefois, une vigilance architecturale s’impose lors de l’usage de sapply() : selon la structure exacte des éléments traités et la présence éventuelle de dimensions résiduelles, cette fonction peut occasionnellement tenter de simplifier le retour sous la forme d’un tableau à deux dimensions ou d’une liste complexe si la longueur des modalités n’est pas uniforme. Dans ce cas de figure précis, l’alternative lapply() encapsulée dans une reconstruction explicite de tableau de données constitue le rempart ultime contre les déformations dimensionnelles inattendues.
5. Méthode 3 : Automatisation globale du data frame avec data.matrix() et is.factor
5.1 Mécanique opérationnelle de la fonction data.matrix()
Lorsqu’un chercheur souhaite préparer l’intégralité d’un tableau de données pour des calculs d’algèbre matricielle, l’usage de la primitive interne data.matrix() développée dans le socle base de R représente une solution éprouvée. Contrairement à la fonction générique as.matrix() qui transforme l’intégralité d’une structure en matrice de caractères textuels dès qu’une seule chaîne y est détectée, data.matrix() applique un traitement sélectif et asymétrique à chaque vecteur atomique.
Son algorithme interne procède à un balayage des colonnes : les vecteurs déjà typés sous forme numérique, entière ou double sont conservés dans leur état d’origine, tandis que les vecteurs de type facteur et les vecteurs de caractères sont systématiquement convertis en entiers positifs reflétant leurs indices internes de modalités. Le produit final de cette procédure n’est plus un tableau hétérogène de données, mais une matrice pure à deux dimensions, peuplée exclusivement de nombres réels ou d’entiers.
Cette structure matricielle résultante se révèle immédiatement exploitable par les bibliothèques d’analyse spectrale, d’optimisation non linéaire ou de factorisation de matrices non négatives, qui exigent toutes une mémoire contiguë et un type de données uniformisé sans la surcharge métaphorique des structures de listes S3 propres aux data.frames.
5.2 Filtrage dynamique combiné avec sapply(df, is.factor)
Bien que la création d’une matrice pure soit avantageuse pour l’algèbre linéaire, de nombreuses étapes de modélisation intermédiaire nécessitent de conserver impérativement le format data.frame, notamment pour exploiter la syntaxe des formules symboliques couramment utilisées dans des fonctions comme lm() ou glm(). Pour automatiser la conversion de tous les facteurs sans altérer le conteneur originel, une approche hautement sophistiquée combine l’indexation logique conditionnelle et data.matrix().
La mise en œuvre s’effectue en interrogeant d’abord la base par l’intermédiaire du filtre sapply(df, is.factor), qui extrait un masque booléen identifiant chaque colonne factorielle. Il suffit ensuite d’appliquer la règle d’assignation directe suivante : df[sapply(df, is.factor)] <- data.matrix(df[sapply(df, is.factor)]). Par cette instruction concise, le sous-ensemble constitué de l’ensemble des variables qualitatives est simultanément converti en nombres entiers via le moteur interne de data.matrix(), puis réinjecté avec précision dans les colonnes correspondantes du tableau de départ.
Ce procédé présente l’immense mérite de préserver intégralement les colonnes non qualitatives, telles que les variables de temps, les scores standardisés continus ou les indicateurs logiques, garantissant une étanchéité absolue du reste du bloc de données face aux transformations typologiques.
5.3 Robustesse sur les jeux de données complexes et volumineux
Dans le domaine contemporain des mégadonnées en sciences comportementales, telles que les grandes enquêtes longitudinales internationales hébergeant des cohortes dépassant dix mille participants sur des centaines de descripteurs, la robustesse algorithmique devient une priorité opérationnelle critique. L’architecture combinée du filtrage dynamique par is.factor et de la transformation numérique groupée démontre une tolérance exceptionnelle aux architectures de données hétérogènes et bruitées.
Cette technique gère avec une résilience parfaite les colonnes présentant des mélanges de classes inattendus, minimisant les risques d’interruption brutale de script durant les pipelines d’analyses automatisés. En exploitant les capacités intrinsèques de data.matrix(), le code évite l’instanciation de multiples variables intermédiaires temporaires dans l’espace de travail global, ce qui limite considérablement l’empreinte mémoire volatile requise.
Dans une optique de science ouverte et d’assurance qualité logicielle, cette standardisation permet d’intégrer des routines de nettoyage génériques au sein de paquets d’analyse reproductibles, assurant ainsi aux équipes scientifiques un comportement stable indépendamment des particularités de nommage ou du volume spécifique des jeux de données traités.
6. Distinction essentielle entre variables nominales et ordinales
6.1 Spécificités des échelles de Likert en psychologie
La pratique consistant à numériser sans discernement toute variable catégorielle dissimule un danger conceptuel majeur, tout particulièrement lors du traitement des échelles de Likert, omniprésentes dans la recherche psychologique et comportementale. Une échelle de Likert présente généralement entre quatre et sept modalités d’accord échelonnées, allant par exemple de « Pas du tout d’accord » à « Tout à fait d’accord ». Lorsqu’un chercheur attribue mécaniquement les valeurs 1 à 5 à ces échelons, il postule implicitement l’hypothèse forte de l’équidistance des intervalles métriques.
Ce postulat sous-tend que la distance psychologique subjective séparant « Pas du tout d’accord » de « Pas d’accord » est strictement identique à celle séparant « D’accord » de « Tout à fait d’accord ». Or, de multiples travaux en théorie de la réponse aux items (IRT) démontrent que la progression le long du trait latent n’est que rarement linéaire sur les échelles d’attitudes subjectives. Transformer ces modalités en nombres cardinaux sans précaution introduit une déformation de la métrique sous-jacente.
Le risque s’amplifie encore dramatiquement lorsque cette opération est infligée à des variables purement nominales sans hiérarchie inhérente, comme la confession religieuse, le groupe ethnique ou la zone géographique. Assigner des entiers arbitraires à de tels indicateurs confère à la variable une relation d’ordre fictive qui induira inéluctablement en erreur toute méthode de régression ou d’apprentissage non supervisé reposant sur des métriques euclidiennes.
6.2 Gestion des facteurs ordonnés via ordered() et factor(…, ordered = TRUE)
Afin de prévenir ces glissements épistémologiques et d’indiquer formellement la présence d’une hiérarchie naturelle sans pour autant assumer la continuité métrique, le langage R intègre la classe spécialisée des facteurs ordonnés. Une variable de cette classe s’instancie au moyen de la commande explicite factor(x, ordered = TRUE, levels = c(…)) ou via la fonction dédiée ordered(). Dès lors, l’objet se voit assigner la double classe c(« ordered », « factor »).
Sur le plan de l’architecture logicielle, un facteur ordonné conserve en mémoire la même représentation par entiers discrets qu’un facteur standard. Cependant, les méthodes S3 associées réagissent de façon radicalement différente. Par exemple, l’application de unclass() sur un facteur ordonné préserve l’intégrité de la hiérarchie tout en extrayant le vecteur de rangs, ce qui permet d’alimenter directement des procédures non paramétriques robustes comme les coefficients de corrélation de rang de Spearman ou de Kendall.
De surcroît, lorsqu’un facteur ordonné est injecté au sein d’une formule de modèle linéaire général, R modifie automatiquement sa matrice de conception par défaut, délaissant les contrastes de traitement conventionnels au profit de contrastes polynomiaux orthogonaux, lesquels estiment spécifiquement les tendances linéaires, quadratiques ou cubiques le long des échelons ordonnés.
6.3 Implications sur la validité des conclusions psychométriques
L’assimilation aveugle d’indices catégoriels numérisés à des grandeurs d’intervalles pose de graves menaces pour la validité interne et externe des conclusions de recherche publiées dans la littérature psychologique. Le calcul de la moyenne arithmétique et de l’écart-type sur des codes numériques issus de variables catégoriques constitue une infraction méthodologique classique qui déforme la distribution empirique, en masquant les asymétries et la bimorphie éventuelle des choix de réponses.
Dans le domaine des modèles paramétriques, cette violation du postulat de continuité et de distribution normale des résidus peut générer une inflation substantielle du taux d’erreur de première espèce (rejet à tort de l’hypothèse nulle), ou à l’inverse induire une perte tragique de puissance statistique masquant de réels effets comportementaux. Les coefficients de régression obtenus sur des échelles ordinales mal converties deviennent hautement sensibles aux seuils de catégorisation arbitraires adoptés par les concepteurs du test.
Dès lors, les standards méthodologiques contemporains préconisent d’expliciter systématiquement la justification du choix de conversion numérique dans la section méthodologique des publications scientifiques. Les chercheurs sont vivement encouragés à démontrer la robustesse de leurs conclusions au moyen d’analyses de sensibilité comparant les modélisations linéaires classiques à des régressions logistiques ordinales à cotes proportionnelles.
7. Le piège critique de la conversion : as.numeric() versus unclass()
7.1 L’erreur classique sur les facteurs à libellés numériques
Parmi l’ensemble des écueils de programmation répertoriés dans l’écosystème R, aucun n’a sans doute provoqué autant de désastres analytiques silencieux que l’usage direct de as.numeric() sur un facteur dont les niveaux représentent eux-mêmes des nombres. Ce scénario d’une trompeuse banalité survient fréquemment lors de l’importation de fichiers tabulaires mal configurés, où des scores continus contenant des caractères non numériques erratiques (comme une apostrophe ou une espace) sont automatiquement assimilés à des colonnes textuelles, puis convertis en facteurs.
Considérons une série temporelle de scores de quotient intellectuel ou d’indices d’anxiété comprenant les valeurs réelles textuelles « 90 », « 100 », « 110 » et « 120 ». Si l’analyste, croyant récupérer ses grandeurs d’origine, applique l’instruction as.numeric(score_facteur), le moteur R n’effectue aucunement une conversion sémantique des caractères textuels vers des réels. À la place, il renvoie fidèlement les indices discrets internes d’allocation des modalités, c’est-à-dire le vecteur 1, 2, 3 et 4.
Cette déformation compresse brutalement l’amplitude de l’échelle d’origine, altérant irrémédiablement la variance, la moyenne et l’ensemble des relations de covariance avec les autres variables du modèle. L’aspect le plus pernicieux de ce comportement réside dans son exécution totalement silencieuse : aucun message d’erreur ni aucun avertissement n’est émis par la console, laissant le chercheur exploiter des données profondément corrompues.
7.2 La solution canonique : as.numeric(as.character(x))
Pour neutraliser ce piège dévastateur et extraire la véritable valeur numérique contenue dans les étiquettes textuelles du facteur, la solution canonique unanimement consacrée au sein de la communauté des développeurs R consiste à forcer une conversion intermédiaire vers le type textuel pur. L’expression consacrée s’écrit : as.numeric(as.character(x)). Ce double emboîtement oblige d’abord le système à dissoudre la structure interne du facteur pour substituer aux indices entiers le vecteur textuel littéral des niveaux, avant que as.numeric() ne convertisse ces chaînes de caractères en grandeurs flottantes réelles.
Cependant, sur le plan computationnel, l’instanciation transitoire d’un volumineux vecteur de chaînes de caractères par as.character() s’avère particulièrement gourmande en ressources mémoire et peut dégrader les performances d’exécution lors du traitement de jeux de données massifs. Pour pallier cet inconvénient tout en garantissant une précision absolue, une alternative élégante et hautement optimisée repose sur l’indexation matricielle directe du dictionnaire de niveaux : as.numeric(levels(x))[x].
Cette syntaxe avancée commence par convertir le petit vecteur de niveaux en nombres réels une seule et unique fois, puis utilise le vecteur d’entiers sous-jacent x pour extraire instantanément la valeur quantitative correspondante. Cette technique réduit drastiquement la sollicitation du ramasse-miettes et maximise le débit computationnel.
7.3 Arbre de décision méthodologique pour le praticien
Afin de guider le praticien à travers le dédale des mécanismes de conversion numérique, il apparaît judicieux de formaliser les critères de sélection sous la forme d’un arbre décisionnel logique et systématique. L’analyste doit en premier lieu poser une question fondamentale : la variable factorielle manipulée représente-t-elle des catégories qualitatives pures ou des valeurs numériques encodées accidentellement sous forme de texte ?
Dans l’éventualité où la variable code des valeurs numériques réelles (par exemple des milligrammes de substance, des âges calendaires ou des pourcentages de réussite), l’approche incontournable réside exclusivement dans l’emploi de as.numeric(as.character(x)) ou de sa variante optimisée as.numeric(levels(x))[x]. Tout recours à unclass() dans ce contexte précis constitue une faute méthodologique rédhibitoire écrasant les grandeurs physiques observées sous des indices de rang.
Dans l’éventualité inverse où la variable code des catégories qualitatives intrinsèques (par exemple des groupes expérimentaux ou des échelons de Likert hiérarchisés), le recours à unclass() ou à data.matrix() représente le chemin canonique préconisé pour extraire les indices de modalité discrets. L’insertion de points de contrôle automatisés en amont et en aval de cette opération, via l’affichage systématique de tableaux croisés des fréquences marginales, permet de certifier que la cardinalité et la correspondance empirique des niveaux ont été rigoureusement respectées.
8. Techniques alternatives et avancées : Codage disjonctif et contrastes
8.1 Création de variables indicatrices (Dummy Coding) avec model.matrix()
Lorsque la structure théorique d’une variable catégorielle nominale interdit toute assignation d’un indice numérique scalaire unique sous peine d’induire une fausse métrique d’ordre, la stratégie de référence en statistique inférentielle repose sur la création de variables indicatrices, universellement désignée sous le terme de codage disjonctif ou dummy coding. Ce procédé consiste à décomposer une variable catégorielle à k modalités en un ensemble de colonnes binaires ne prenant que les valeurs 0 ou 1, chacune signalant la présence ou l’absence d’un niveau spécifique.
Au sein de R, la formulation la plus robuste et la plus puissante pour générer cette expansion matricielle réside dans l’utilisation de la fonction model.matrix() combinée à la syntaxe des formules mathématiques. En formulant l’instruction model.matrix(~ variable – 1, data = df), l’analyste instancie une matrice de conception complète comportant autant de colonnes binaires que de modalités existantes, l’opérateur – 1 supprimant l’ordonnée à l’origine globale pour éviter les contraintes de sur-identification.
Il convient toutefois de souligner l’impératif méthodologique lié au piège de la colinéarité stricte, souvent désigné sous l’expression anglo-saxonne de dummy variable trap. Dans le cadre de régressions linéaires standards intégrant une constante d’interception, conserver l’intégralité des k colonnes engendre une singularité matricielle fatale, la somme des colonnes binaires étant rigoureusement égale au vecteur unitaire de l’interception. Il est dès lors indispensable de supprimer l’une des colonnes, laquelle fait dès lors office de catégorie de référence théorique.
8.2 Codage par contrastes statistiques
R affine ce paradigme en intégrant nativement un système d’assignation de contrastes statistiques modifiant la manière dont les facteurs sont décomposés numériquement lors de l’estimation des modèles linéaires. La commande contrasts() permet de visualiser ou de redéfinir la matrice de pondération attribuée à un facteur donné. Par défaut, R applique sur les facteurs non ordonnés le schéma contr.treatment, qui correspond précisément au codage indicatrice standard opposant chaque modalité successive au premier niveau pris comme référence.
Cependant, d’autres structures de contrastes s’avèrent infiniment plus pertinentes pour répondre à des interrogations de recherche complexes. Les contrastes polynomiaux, paramétrés via contr.poly, constituent l’option par défaut pour les facteurs ordonnés et permettent de tester la nature géométrique de la réponse comportementale à travers des composantes d’ordre supérieur. Pour les analyses en psychophysique ou dans les protocoles chronométriques, les contrastes de Helmert, instanciés via contr.helmert, comparent chaque modalité successive à la moyenne pondérée des modalités qui la précèdent, isolant ainsi l’effet incrémental de seuils de stimulation sensorielle croissants.
Cette approche par contrastes permet de transcender la simple conversion typologique pour infuser des hypothèses scientifiques formelles au cœur même de la paramétrisation numérique des variables explicatives qualitatives.
8.3 One-Hot Encoding dans les cadres d’apprentissage statistique
Dans l’écosystème contemporain de l’apprentissage statistique supervisé et non supervisé, la transformation de variables qualitatives en matrices binaires est universellement formalisée sous le vocable d’encodage One-Hot. Des cadres de modélisation avancés tels que caret ou la suite moderne tidymodels via le paquetage recipes proposent des pipelines industriels dédiés à cette tâche, notamment par l’intermédiaire de la spécification déclarative step_dummy().
L’un des défis prépondérants auxquels cette approche se heurte concerne la gestion rigoureuse des modalités rares, bruitées ou totalement absentes lors de la phase de calibrage de l’algorithme. Si un participant d’un échantillon de validation présente une modalité inédite jamais observée dans le jeu d’entraînement, un encodage naïf provoquera une rupture immédiate de conformité dimensionnelle. Les recettes d’encodage modernes remédient à cela en intégrant des paramètres d’agrégation dynamique, assignant automatiquement les niveaux marginaux à une modalité résiduelle composite désignée sous le terme d' »Autre ».
Il importe néanmoins de garder à l’esprit l’impact physique de cette pratique sur la complexité computationnelle. Le déploiement effréné du One-Hot Encoding sur des variables possédant une cardinalité élevée (comme un code postal ou une affiliation institutionnelle) amplifie dramatiquement la sparsité (proportion d’éléments nuls) de la matrice finale, augmentant l’empreinte mémoire et exacerbant le fléau de la dimensionnalité au détriment des capacités de généralisation du modèle comportemental.
9. Intégration moderne au sein de l’écosystème Tidyverse
9.1 Conversion déclarative avec dplyr::mutate et dplyr::across
L’avènement de l’univers Tidyverse, structuré autour des principes directeurs formalisés par Hadley Wickham, a profondément repensé l’ergonomie de l’ingénierie des données en R en substituant à l’impératif procédural une grammaire déclarative particulièrement élégante. Au cœur de cette philosophie, le paquetage dplyr orchestre les transformations vectorielles au moyen du verbe pivot mutate() combiné à l’opérateur d’envergure across().
Cette syntaxe fluide s’affranchit des assignations manuelles risquées sur les indices de sous-ensembles matriciels. Pour convertir simultanément l’ensemble des facteurs d’un tableau d’observations sans altérer les tiers de manière intempestive, l’analyste formule l’expression suivante : df <- df %>% mutate(across(where(is.factor), unclass)). L’association harmonieuse de la fonction de sélection conditionnelle where(is.factor) et de la primitive de décomposition unclass garantit une clarté de lecture inégalée et une maintenance logicielle exemplaire du flux de travail.
L’immense valeur ajoutée de cette formulation déclarative réside dans son intégration transparente au sein d’un pipeline complet articulant successivement le filtrage des lignes, le regroupement conditionnel par sous-populations et la conversion numérique finale, favorisant ainsi la traçabilité intégrale des transformations au sein de la chaîne de recherche.
9.2 Recodage explicite et manipulation d’indices avec forcats
La gestion sémantique rigoureuse des modalités trouve son aboutissement technique dans le paquetage spécialisé forcats, partie intégrante du Tidyverse conçue spécifiquement pour domestiquer les comportements parfois récalcitrants des facteurs. Avant d’exécuter une conversion vers le format numérique, la réorganisation explicite et contrôlée des niveaux s’avère fréquemment nécessaire pour garantir que l’indice 1 soit rigoureusement attribué à la modalité témoin ou fondamentale de l’étude.
Les fonctions fct_relevel() permettent d’assigner manuellement l’agencement exact des niveaux, tandis que fct_infreq() ordonne les modalités selon leur fréquence empirique d’apparition au sein de l’échantillon, octroyant ainsi les plus petits indices entiers aux réponses les plus prévalentes. Dans les contextes où des catégories à très faible effectif menacent la stabilité des estimations, la fonction fct_lump() opère une fusion sélective préalable des modalités clairsemées au sein d’une étiquette unifiée avant que la numérisation ne fige la structure discrète.
Cette étape préalable de standardisation via forcats supprime l’aléa lié aux classements alphabétiques implicites de base, conférant au processus de numérisation une nature strictement déterministe et reproductible lors du déploiement du code sur de nouvelles cohortes de sujets.
9.3 Interactions avec les tibbles et conservation des attributs
L’exploitation conjointe des méthodes de conversion numérique et des structures de données modernes de type tibble (variante enrichie du data.frame traditionnel) requiert une compréhension fine du comportement des attributs sous-jacents. Par conception, les tibbles adoptent une politique d’ingénierie stricte : ils refusent les conversions automatiques de types, émettent des avertissements proactifs face aux comportements incertains et s’interdisent le recyclage implicite des dimensions vectorielles.
Lorsque la fonction unclass() est injectée à l’intérieur d’un appel à mutate() sur un tibble, ce dernier préserve la nature vectorielle résultante tout en éliminant proprement la classe S3 factor. Cependant, si le vecteur sous-jacent héberge des attributs atypiques (comme des libellés de variables hérités de logiciels tiers tels que SPSS ou SAS), le tibble est susceptible de maintenir ces métadonnées orphelines, ce qui peut occasionner des frictions avec certaines fonctions de modélisation mathématique stricte de R de base.
Il convient donc fréquemment, lors de l’intégration dans des routines nécessitant des matrices d’algèbres linéaires pures, de procéder à un « strippage » contrôlé des classes via des wrappers légers garantissant que l’objet résultant est rigoureusement conforme au format d’entier atomique standard exempt de scories métatextuelles.
10. Traitement des valeurs manquantes et anomalies lors de la conversion
10.1 Propagation et gestion des NA sous unclass() et data.matrix()
L’administration de protocoles expérimentaux et d’enquêtes psychologiques s’accompagne inévitablement du phénomène des valeurs manquantes (notées NA dans le langage R). La préservation scrupuleuse de ces omissions lors de la métamorphose numérique conditionne l’exactitude des inférences statistiques futures. Sous l’action de la fonction fondamentale unclass(), le moteur préserve scrupuleusement la sémantique de l’absence : un élément manquant au sein du facteur est converti de manière totalement transparente en un entier manquant de type NA_integer_, sans décaler la séquence d’indexation des réponses valides.
De même, la primitive data.matrix() assure une propagation parfaitement intègre de ces absences structurelles en inscrivant des valeurs NA_real_ au sein de la matrice résultante. La vigilance de l’expérimentateur doit toutefois redoubler d’intensité lorsque des niveaux explicites de valeurs manquantes ont été artificiellement greffés au facteur via la commande addNA(). Dans cette configuration singulière, R ne considère plus l’omission comme un vide de données, mais bel et bien comme une catégorie observationnelle à part entière.
Par conséquent, unclass() lui attribuera un indice entier valide (généralement k+1), transformant de facto une donnée manquante non aléatoire en un score numérique fictif. Cette méprise algorithmique est de nature à introduire un biais massif d’estimation dans les modèles comportementaux si l’analyste omet de re-filtrer ces indices spécifiques avant le calcul des paramètres.
10.2 Diagnostics d’incohérence et gestion des niveaux orphelins
Une anomalie structurelle récurrente au sein des bases de données de recherche comportementale réside dans l’émergence de ce que la théorie des données nomme les niveaux orphelins ou facteurs inutilisés (unused levels). Ce phénomène survient lorsqu’une modalité théorique a été formellement déclarée au sein du dictionnaire des niveaux du facteur, mais qu’aucune observation de l’échantillon réel ne porte effectivement cette valeur (souvent suite au sous-échantillonnage d’une population clinique rare ou au filtrage drastique d’une partie des participants sur critères d’exclusion chronométriques).
Si l’analyste procède à une conversion numérique par unclass() sans assainissement préalable, la modalité orpheline conservera son rang théorique au sein de la nomenclature des entiers, créant ainsi des « trous » ou des discontinuités dans l’espace d’états empirique de la variable quantifiée (par exemple des scores sautant brutalement de 2 à 4 sans aucune observation pour l’entier 3). Si cette préservation de l’espace métrique théorique peut être souhaitable dans certaines approches de standardisation de tests, elle se révèle toxique pour d’autres algorithmes exigeant une numérotation séquentielle stricte et continue.
L’administration prophylactique de la fonction droplevels() sur la variable factorielle avant toute tentative de numérisation permet d’élaguer sans délai l’ensemble des niveaux vides. Cette purge structurelle recompacte l’espace indiciel, garantissant une suite d’entiers discrets consécutifs strictement représentative des données empiriquement observées.
11. Études de cas appliquées en sciences psychologiques et cognitives
11.1 Cas 1 : Conversion d’une échelle d’évaluation de la dépression (PHQ-9)
Le Patient Health Questionnaire (PHQ-9) constitue l’un des instruments psychométriques les plus universellement administrés pour dépister et quantifier la sévérité des épisodes dépressifs en milieu clinique. Cet inventaire se compose de neuf items formulés sous la forme d’affirmations symptomatiques, face auxquelles le patient sélectionne l’une des quatre options qualitatives ordonnées suivantes : « Jamais », « Plusieurs jours », « Plus de la moitié du temps », et « Presque tous les jours ». Lors de l’acquisition des données au sein des plateformes de passation en ligne, ces réponses sont typiquement exportées sous la forme de facteurs ou de chaînes de caractères.
Pour préparer ces données à l’évaluation clinique, il est impératif de traduire ces réponses en un format numérique échelonné strictement de 0 à 3, afin que leur sommation donne lieu au score global conventionnel du PHQ-9 compris entre 0 et 27 points. Une conversion naïve via unclass() sans calibrage attribuerait l’échelle 1 à 4, induisant une translation artificielle de 9 points sur le score final de chaque participant, faussant dramatiquement les seuils diagnostiques établis.
Le protocole opératoire méthodique exige ainsi de fixer formellement la hiérarchie des niveaux en invoquant factor(item, levels = c(« Jamais », « Plusieurs jours », « Plus de la moitié du temps », « Presque tous les jours »)). L’analyste procède ensuite à la vectorisation sur les neuf items via sapply() couplé à une décrémentation unitaire : phq_numerique <- sapply(df[, 1:9], unclass) – 1. Cette matrice assainie autorise l’estimation immédiate de la consistance interne via le calcul de l’alpha de Cronbach ainsi que l’extraction du score diagnostique composite par la fonction rowSums().
11.2 Cas 2 : Préparation des variables indépendantes d’une expérience cognitive
Examinons désormais un protocole de psychologie expérimentale exploitant un paradigme d’amorçage attentionnel de type Stroop, au sein duquel des chercheurs manipulent deux variables indépendantes intra-sujet : la « Condition de Congruence » (trois modalités : « Congruent », « Neutre », « Incongruent ») et la « Modalité Sensorielle de Présentation » (deux modalités : « Visuelle », « Auditive »). Les temps de réaction vocaux (en millisecondes) constituent la variable dépendante d’intérêt. Pour modéliser ces chronométries au moyen d’un modèle linéaire mixte sous le paquetage lme4, une préparation matricielle des variables catégorielles s’impose.
L’application directe de data.matrix() sur le tableau de conception expérimentale permet de transformer simultanément les deux facteurs en prédicteurs discrets d’une matrice numérique pure, convenant aux routines d’optimisation mathématique du gradient de déviance. Cette formulation matricielle permet d’isoler explicitement la matrice des effets fixes.
L’expérimentateur avisé utilise cette numérisation pour inspecter les corrélations empiriques entre prédicteurs expérimentaux avant injection dans la syntaxe lmer(). La conversion garantit en outre que le traitement des interactions de haut niveau entre la modalité perceptive et le conflit cognitif s’appuie sur une paramétrisation numérique sans faille, évitant tout arrêt d’estimation imputable à une matrice de dispersion singulière ou mal conditionnée.
11.3 Cas 3 : Prétraitement de données d’enquête socio-comportementale à large échelle
Considérons l’exploitation d’une vaste base de données socio-comportementale rassemblant cinquante indicateurs qualitatifs et quantitatifs hétérogènes prélevés sur un échantillon représentatif de vingt mille citoyens. Ce jeu de données imbrique des caractéristiques démographiques nominales, des échelles d’attitudes politiques ordinales et des métriques de revenus continues. L’objectif analytique consiste à exécuter une réduction de dimensionnalité via une Analyse en Composantes Principales (ACP) ou une factorisation matricielle.
Le protocole de prétraitement automatisé mobilise l’association experte du filtrage dynamique et de la réassignation vectorisée : colonnes_cat <- sapply(base_socio, is.factor) ; base_socio[colonnes_cat] <- lapply(base_socio[colonnes_cat], function(col) as.numeric(unclass(col))). Ce bloc d’instructions identifie de manière totalement autonome chaque vecteur factoriel et lui applique la conversion tout en préservant intacte la classe data.frame globale de l’archive.
L’étape conclusive de ce pipeline consiste à dérouler un audit qualité automatisé post-conversion. Par l’extraction des sommes de valeurs manquantes par colonne et la vérification des matrices de variances marginales, l’équipe s’assure qu’aucune variance n’a été artificiellement écrasée à zéro par une fausse attribution de modalité, garantissant une intégrité complète des données préalable aux analyses multivariées.
12. Synthèse méthodologique, performances computationnelles et recommandations
12.1 Analyse comparative des performances : benchmark d’exécution
Dans un contexte où les impératifs computationnels contraignent les flux de calcul sur les grands volumes de données empiriques, l’évaluation de la performance pure des primitives de R s’avère hautement instructive. Un benchmark microsecondaire rigoureux, conduit au moyen du paquetage dédié microbenchmark sur un vecteur synthétique de dix millions d’observations qualitatives, met en lumière des disparités d’efficacité spectaculaires entre les approches théoriquement interchangeables.
La primitive unclass() écrase systématiquement la concurrence en matière de vitesse brute, affichant un temps moyen d’exécution quasi nul. Ce résultat découle directement de son absence d’allocation de nouvelle mémoire : unclass() se borne à altérer l’en-tête de métadonnées du pointeur S3 en langage C sans dupliquer le tableau des entiers sous-jacent. À l’inverse, l’invocation de as.numeric(as.character(x)) accuse un coût computationnel titanesque, souvent supérieur d’un facteur 50 à 100, imputable à l’obligation pour le moteur d’allouer des millions de chaînes de caractères au sein de la table globale de hachage de R, avant de devoir les ré-analyser séquentiellement pour en déduire des valeurs flottantes.
De son côté, la fonction data.matrix() se situe à un niveau de performance intermédiaire très honorable : bien qu’elle opère une copie mémoire intégrale pour créer la matrice bidimensionnelle de destination, son code sous-jacent exécuté en code machine compilé lui assure un débit de traitement de données exceptionnellement véloce, positionnant cette fonction comme le choix d’excellence pour la transformation globale de blocs tabulaires complets.
12.2 Bonnes pratiques pour la science ouverte et la reproductibilité
Au terme de cette analyse technique et théorique des mécanismes de numérisation des variables qualitatives au sein de l’environnement R, il convient de cristalliser les règles fondamentales garantissant l’alignement des analyses comportementales sur les principes d’intégrité de la science ouverte et de la reproductibilité computationnelle (principes FAIR : Facile à trouver, Accessible, Interopérable et Réutilisable).
La première règle de bonne pratique impose la ségrégation stricte des données brutes et des scripts de métamorphose. Les fichiers de données sources ne doivent sous aucun prétexte faire l’objet de modifications manuelles au sein de tableurs externes. Toutes les conversions numériques de facteurs doivent être intégralement scriptées, versionnées via des systèmes de contrôle de code source, et commentées au sein de documents computationnels dynamiques de type Quarto ou R Markdown.
La seconde recommandation cardinale exige le stockage persistant et l’exportation systématique des tables de correspondance (codebooks). Chaque fois qu’une variable catégorielle fait l’objet d’une assignation d’indices numériques par unclass() ou par contrastes, un tableau synoptique associant chaque modalité textuelle d’origine à son entier cible doit être généré et déposé aux côtés du jeu de données final au sein d’entrepôts de données scientifiques ouverts. Seule cette discipline méthodologique sans compromis permet de préserver la sémantique profonde des observations psychologiques tout en autorisant l’exploitation sans limite de la puissance computationnelle contemporaine.
Références
- Ihaka, R., & Gentleman, R. (1996). R: A language for data analysis and graphics. Journal of Computational and Graphical Statistics, 5(3), 299-314. https://doi.org/10.1080/10618600.1996.10474713
- Kroonenberg, P. M. (2008). Applied Multiway Data Analysis. John Wiley & Sons. https://doi.org/10.1002/9780470238998
- Lord, F. M., & Novick, M. R. (1968). Statistical Theories of Mental Test Scores. Addison-Wesley.
- R Core Team. (2023). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. https://www.R-project.org/
- Stevens, S. S. (1946). On the theory of scales of measurement. Science, 103(2684), 677-680. https://doi.org/10.1126/science.103.2684.677
- Wickham, H. (2019). Advanced R (2nd ed.). Chapman and Hall/CRC. https://doi.org/10.1201/9781351201315
- Wickham, H., Averick, M., Bryan, J., Chang, W., McGowan, L. D., François, R., Grolemund, G., Hayes, A., Henry, L., Hester, J., Kuhn, M., Pedersen, T. L., Miller, E., Bache, S. M., Müller, K., Ooms, J., Robinson, D., Seidel, D. P., Spinu, V., Takahashi, K., Vaughan, D., Wilke, C., Woo, K., & Yutani, H. (2019). Welcome to the Tidyverse. Journal of Open Source Software, 4(43), 1686. https://doi.org/10.21105/joss.01686