IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage R++ Discussion :

[En vrac] 1. Structure des données


Sujet :

Langage R++

  1. #1
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Septembre 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2007
    Messages : 214
    Points : 816
    Points
    816
    Par défaut [En vrac] 1. Structure des données
    [EDIT = Pour ceux qui n'ont pas le temps de lire toutes les propositions, je modifie régulièrement le premier post afin qu'il prenne en compte les remarques qui sont faites dans les posts suivants]

    1 Structure des données

    1.1 Types récursifs

    On pourrait aussi définir des types basiques. Puis définir :
    • vecteur : une suite de variables du même type (y compris les dimensions)
    • liste : une suite de variables de types différents.

    Le vecteur et liste peuvent s'appliquer à eux-mêmes (type récursifs).
    Une matrice est un vecteur de vecteur ; un data.frame serait un vecteur de liste. Mais on pourrait aussi définir des choses plus complexe comme des vecteurs de data.frame, ou des data.frame qui contiendraient des matrices...

    Note importante : Classiquement, M[1,2] désigne la 1° ligne et 2° colonne...
    Il faut donc qu'une matrice soit construite comme un vecteur colonne constitué de vecteurs lignes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    V1 = (11,14)
    V2 = (12,15)
    V3 = (13,16)
    
        (V1)   (11,14) 
    M = (V2) = (12,15)
        (V3)   (13,16)
    Ainsi M[1,2] signifiera : 1° vecteur ligne V1, puis 2° valeur de V1, soit 14. C'est bien la définition classique.
    De même, un dataFrame doit être un vecteur (colonne) de liste (ligne), chaque liste étant un individu. Ainsi, D[1,2] sera le premier individu , 2° valeur. Définir un dataFrame comme une liste (ligne) de vecteur (colonne), alors D[1,2] serait le premier élément de la liste (première colonne) dont ont prendrait le deuxième élément. La notation serait inversé par rapport à R (et au bon sens).

    Tout cela, c'est du point de vu de l'utilisateur. Du point de vue du code cible, il sera peut-être préférable de code les dataFrame comme des listes de vecteurs, mais il faudra alors inverser la notation : M[1,2] en R++ devra devenir M[2][1].

    Enfin, l'utilisateur n'aura pas a connaitre les subtilités de vecteur colonne de vecteur ligne ou inversement. Pour lui, nous créerons un type matrix qui sera simplement un vecteur colonne de vecteur ligne. Idem pour les dataFrame.


    1.2 Gestion automatiques des types

    On veut un langage à deux niveaux : simple pour l’utilisateur (le médecin) qui n’y connait rien, plus sophistiqué pour l’expert. En conséquence :
    • Pour le non expert : Si l’utilisateur ne précise rien (déclaration simple), alors tous les types integer de R++ sont des long (C ou Java) ; les numeric de R++ sont des doubles (C ou Java).
    • Pour l’expert : il a possibilité de forcer le format et de déclarer des integer comme des short, int, ou long, les numeric comme des float ou des doubles.
    • Option « optimisation de la mémoire » : Il est également possible de typer dynamiquement lors de l’exécution. Cela sera une option à spécifier dans le programme, option qui sera utilisée lors de la compilation. Initialement, tous les integer R++ sont des short. Si un short dépasse sa capacité, il est dynamiquement transformé en int, puis s’il grandi encore en long. Idem pour les float. Naturellement, on perdra en efficacité. C'est pour cela que ca sera une option de compilation.


    1.3 Typé non explicitement.

    Du point de vue du néophyte, l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass a <- new MaClass()
    est un peu étrange car on écrit deux fois MaClass. Il faudrait simplifier. De plus, il n’est pas vraiment nécessaire de dire le premier MaClass. Il serait suffisant de dire :
    ou encore mieux :
    Pour les types de base, comme il n’y a pas ambiguïté possible, on peut même supprimer le type :
    Ensuite, le typeur fabrique automatiquement le type de b.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    True : logical
    3 : integer
    3.0 : numeric
    "L2" : character
    "L2" in ("L1"<"L2"<"L3") : ordered
    "Z" in ("A","E","Z","F") : factor
    Bien sur, on pourra forcer le type :
    Si on veut déclarer sans initialiser (l’équivalent de int a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    b <- integer()
    a <- maClass()

    1.4 Nombre

    Autoriser les héxadécimaux via 0x et les binaire via 0b. Généraliser ? Permettre de travailler en base 3, en base 60 (0-9,A-Z,AA-AX) and so on ?

    1.5 Indices de tableau et matrice

    Les indices des tableaux (et matrice) doivent commencer a 1, et non à 0

    1.6 Déclaration des variables

    On peut les déclarer n’ importe où (et pas seulement dans l’entête comme dans certains langages).

    1.7 Transtypage

    Pas de transformation automatique d’un boolean en integer, surtout pas de transformation automatique d’un char en integer.

    Pour les transtypages de nombre, a voir : integer peut-il devenir automatiquement un numeric ? vecteur peut-il devenir une matrice ? R le fait en recyclant les nombres ou les vecteurs trop court. Personnellement, je penche plutôt pour non sauf dans le cas integer <-> numeric.

    Dans tous les cas, un transtypage "rétrécissant" (genre numeric vers integer, ou matrice d'une colonne vers vecteur) qui rétrécit effectivement (par exemple 1.5 transformé en entier, ou bien la matrice avait en fait deux colonnes) doit déclencher une erreur.


    1.8 Transtypage automatique

    Le transtypage entre objet définit par l’utilisateur doit pouvoir exister (être définit par l’utilisateur comme une méthode).

    1.9 Gestion des dates

    Les dates sont des integer avec un habillage.


    1.10 Type (en vert, ce qui a été rendu obsolète par un autre point, ou par une réponse)

    A priori, on prend les mêmes types de base que java, puis on définit des surtypes qui reprennent les types de bases et qui ajoute factor, ordered et date (qui sont des integer).
    Idéalement, il faudrait « cacher » le vrai type à l’utilisateur. Il manipulerait des integer, le programme choisirait tout seul si c’est des int, des short ou des long. Idem pour les float et double.



    1.11 Infini

    Pour chaque type numeric, les valeurs +infini et –infini existent. Elles sont le plus grand et le plus petit nombre du type. Du coup, l’algèbre est modifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    > a<-250 
    > b<-250 
    > c <- a^b
    > print(c)
    [1]+inf \\ et non une valeur négative comme en java

    1.12 Initialisation

    On propose une initialisation par défaut à NA ? Le problème ne se pose plus car on a supprimé la déclaration explicite : la déclaration se fait en même temps que l’affectation. Eventuellement, la déclaration se fait en utilisant un constructeur vide, ce qui créer un objet vide.

    Ou bien ou impose une initialisation systématique de tout ? Oui, mais éventuellement vers l’objet vide.
    Pour les tableaux, obliger à initialiser peut poser problème. Effectivement. Mais comme il n’y a plus de déclaration, ca ne pose pas de problème. On a le choix : non initialisation (ou initialisation à vide), initialisation à NA ou initialisation classique


    1.13 Les manquantes

    Il faut pouvoir définir plusieurs types de manquantes : soit NA, soit NA1, NA2, NA3, NA4, NA5 (pour « non renseigné », « illisible », « aberrantes »…

    1.14 Déclaration d’un tableau

    integer[,] et non pas integer[][]


    1.15 Création de tableaux

    On doit pouvoir faire l’un ou l’autre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int[3] toto, tutu    // simplification de int toto[3], tutu[3]
    int titi[3], tete[5] // vrai syntaxe (elle offre plus de liberté)
    Christophe
    Porteur du projet R++ https://rplusplus.com
    YouTubeur https://www.youtube.com/c/lesstatsmemepasmal

  2. #2
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Août 2013
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Commentaires correspondant au document primitif "enVrac" qui a été visiblement modifié ensuite.

    ------------------------------------------------------------------------

    1. Structure des données

    1.1 Gestion automatique des types

    Pourquoi pas, mais la gestion mémoire est plus complexe et l'extension automatique ne va pas améliorer le temps d'exécution. Du point de vue interne, pour les opérations arithmétiques, il faudra probablement utiliser la même taille mémoire pour les opérandes ... (bytecode style).

    1.1 Types récursifs
    OK mais imbriqués ou récursifs*?
    Une structure dont un élément est de même type que la structure elle-même*?

    1.3 Typé non explicitement
    En Java (et d'autres langages objets), la définition d'une classe définit un type et une sous-classe un "sous-type", ce qui permet de faire des conversions (...) à partir de la hiérarchie de l'héritage.

    Ma pratique de Java (et de C++) me pousse à favoriser l'écriture
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass maClass = new MaClass( ...)
    (règle de bonne pratique dans la nomination des variables, un peu comme en Java), mais je ne suis peut-être pas le bon "expert" concernant ces aspects lorsqu'il s'agit de R.

    b<-3.5 : j'y vois un problème potentiel.

    Si b était de type int, l'affectation de 3.5 lui donnerait le type float et si on le passe comme paramètre à une fonction qui attend un argument de type int, n'y aurait-il pas un problème ?

    La gestion et le contrôle automatiques des types peuvent-ils résoudre les cas de passage de paramètres aux fonctions ?

    OK pour les déclarations sans initialisations.
    Mais, si en java on peut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaClass a ; a=new MaClass(...)  (ou utiliser le constructeur par défaut avec a =new MaClass() )
    alors qu'est-ce qui différencie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a<-MaClass() (pour la déclaration et :)
    a<-MaClass() (pour instanciation)
    comme proposée, pour simplification, au début de la partie 1.3 (création d'objet) ?

    1.6 Déclaration des variables
    Oui il faudrait qu'on puisse faire les déclarations partout, et cela doit être réfléchi dans le cadre général de la portée des identificateurs. Mais pour une variables dont le "type est une classe" (parag. "Typé non explicitement" dans le document), il faudrait que la classe soit définie avant la déclaration de la variable.

    1.8 Transtypage automatique
    Ce que je comprends de ce paragraphe est que cela est lié à la notion de classe (les objets définis par l'utilisateur) : le principe de l'héritage doit pouvoir fonctionner entre classes (et le typage aussi donc -conversion-)
    Si les classes ne sont pas dans une même hiérarchie .... ça sera difficile et il faudra écrire alors du code de conversion. Même chose pour des objets qui ne sont pas instances de classe de l'utilisateur (instances d'objets de packages) ; je ne parle pas ici des données de type primitif (type primitif est emprunté à java) .

    Dans R, la coercition existe pour résoudre ce type de pb, lorsque les classes n'ont pas la même représentation (page 348 de Programming with R de J.-M. Chambers).

    1.10 Type
    Ce qui serait bien : un tableau donnant les grandes lignes des correspondances des types, étendue des valeurs pour les types primitifs, … (R, R++ et Java si on prend ce langage comme "modèle" pour le typage)

    Concernant les "surtypes", que je rapproche des classes "enveloppes" (wrapper) de Java et la manipulation des données, y a t-il une référence non explicite à l'autoboxing (et l'unboxing) ?


    1. 11 Infini
    J'ai testé, en Java, l'exemple de la puissance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a<-250
    b<-250
    c<-a^b
    en java cela donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int a = 250 ;
    int b = 250 ;
    double  c = Math.pow(a, b) ;
    System.out.println(c)  ;
    ===> cela donne Infinity
    avec System.out.println(-c), cela donne -Infinity

    Donc les résultats en Java sont corrects !

    1. 12 Initialisation
    En 1.3 on parle de déclaration sans initialisation ....
    Je préfère parler de constructeur par défaut que de constructeur vide et à ma connaissance un constructeur par défaut crée un objet non vide mais dont les champs peuvent ne pas avoir été initialisés (que des déclarations par exemple).



    1.14 Déclaration d'un tableau
    en Java, l'exemple donné est une création plus une initialisation.

    1.15 Création de tableaux
    Dans l'exemple donné, il y a donc déclaration et création (au sens java)*?

  3. #3
    Membre éclairé

    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Septembre 2007
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2007
    Messages : 214
    Points : 816
    Points
    816
    Par défaut
    1.1 type récurssif

    On aura
    • des types "basic" (integer, logical,...)
    • des types récurssifs
      • Les vecteurs : une suite d'élément, tous du même type
      • Les listes : une suite d'élément, éventuellement de types différents


    Ainsi, on pourra définir un vecteur d'integer, ou un vecteur d'une liste de (vecteur de character, vecteur de logical), et ainsi de suite.

    Sucre syntaxique, un vecteur de vecteur sera appelé matrice alors qu'une iste de vecteur tous de même longueur sera appelé dataFrame. Mais le vrai type en dessous sera un "type récursif de type recursif de types de base"

    Enfin, si un utilisateur définit la classe "toto", il pourra par exemple faire des vecteurs de liste de vecteur de toto

    1.3
    alors qu'est-ce qui différencie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a<-MaClass() (pour la déclaration et :)
    a<-MaClass() (pour instanciation)
    Rien, car dans l'optique de R++, la déclaration pure sans instanciation n'existe plus.


    1.6
    Mes maigres connaissances dans les langages objets me laissent penser qu'il n'y a pas vraiment d'ordre dans la déclaration des classes... Me trompe-je ?

    1.8
    Le problème que je soulève ici est celui de laisser à l'utilisateur la possibilité de définir lui-même des transtipeurs : il a créé une classe toto et une autre classe titi, l'autorise-t-on à écrire une méthode de toto qui serait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    titi result <- transtyp_toto_titi(){
      resultTiti <- titi()
      transtype toto en titi
      return resultTiti
    }
    et qui permettrait ensuite d'écrire des codes comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    > a <- titi()
    > b <- toto()
    > integer f <- function(toto x){ blabla ; return 0}
    > f(b)
    [1] 0
    > f(a) #  a est automatiquement transtypé en toto
    [1] 0
    Christophe
    Porteur du projet R++ https://rplusplus.com
    YouTubeur https://www.youtube.com/c/lesstatsmemepasmal

Discussions similaires

  1. extraction de la structure des données d'une BD
    Par wallabee dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 01/02/2008, 16h33
  2. Structurer des données dans un tableau
    Par julie75 dans le forum Débuter
    Réponses: 21
    Dernier message: 18/12/2007, 23h20
  3. Structuration des données - macro
    Par bino007 dans le forum Requêtes et SQL.
    Réponses: 0
    Dernier message: 25/11/2007, 20h13
  4. Aide pour diagramme de structure des données
    Par DeezerD dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 04/12/2004, 19h10
  5. Structure des données en retour d'un DBExtract ?
    Par mikouts dans le forum XMLRAD
    Réponses: 4
    Dernier message: 24/01/2003, 15h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo