- Le blog participatif de bioinformatique francophone depuis 2012 -

Cer­tains bio-infor­ma­ti­ciens ne jurent que par R (j'en fais par­tie). Je suis amou­reux de sa sim­pli­ci­té (sic), son élé­gance (re-sic), sa docu­men­ta­tion et ses innom­brables packages tous plus utiles les uns que les autres. Et sur­tout c'est le seul lan­gage que je maî­trise un peu conve­na­ble­ment, alors for­cé­ment je trouve tous les autres lan­gages nuls, en toute objec­ti­vi­té.

Et pour­tant R est uni­ver­sel­le­ment recon­nu comme étant un lan­gage de pro­gram­ma­tion éso­té­rique. Il a fal­lu tout le talent de Patrick Burns et de son livre pour que j'ouvre enfin les yeux et découvre qu'en fait R, c'est l'enfer.

Des­cen­dez donc avec moi dans des pro­fon­deurs abys­sales au tra­vers de quelques exemples libre­ment ins­pi­rés de the R infer­no.

The R Infer­no

R ne sait pas calculer

Défi­nis­sons un joli vec­teur :

Mais à quoi res­semble-t-il ?

Un bien beau vec­teur. Vrai­ment. R sau­ra-t-il trou­ver quelles valeurs sont égales à 0.1 ?

Heu, bien joué R. Quatre bonnes réponses sur sept, c'est… encou­ra­geant. Sur­tout pour un pro­gramme de sta­tis­tiques, très popu­laire, et très uti­li­sé en bioin­fo.

Repre­nons :

Mais pourquoi donc ?

Le pro­blème des nombres à vir­gule, c'est que la par­tie après la vir­gule peut être infi­nie, alors que la mémoire des ordi­na­teurs ne l'est pas. Du coup, les ordi­na­teurs décident plu­tôt de ne gar­der que quelques (dizaines de) nombres après la vir­gule, et d'oublier les autres. Ils font donc plein de petites erreurs de cal­cul débiles. Par défaut, R n'affiche pas tout ce qu'il sait d'un nombre, mais on peut lui deman­der d'en affi­cher plus (le nombre maxi­mum de

digits

  peut dépendre de votre confi­gu­ra­tion) :

Et l'on voit bien en effet que pour notre lan­gage pré­fé­ré, 0.1 n'est pas égal a 0.3/3. You­pi. C'est génial.

Comme en fait c'était quand même gra­vos, les concep­teurs de R, dans leur infi­nie sagesse, ont déci­dé de faire une fonc­tion qui donne le résul­tat atten­du, la mal nom­mée all.equal. Cette fonc­tion com­pare (entre autre) si la dif­fé­rence entre deux nombres est moins impor­tante qu'une petite tole­rance.

Quelques détails :

  • le para­mètre tole­rance vaut par défaut 1,5.10-8.
  • Les concep­teurs de R ont déci­dé que all.equal ne retour­ne­rait pas FALSE (parce que). Du coup, comme ils étaient quand même bien embê­tés, ils ont créé la fonc­tion isTRUE :
  • Pour rendre le tout vrai­ment infer­nal, all.equal n'est évi­dem­ment pas vec­to­ri­sée, débrouillez-vous comme ça.

R, le maître troll des lan­gages de pro­gram­ma­tion…

R est en moyenne assez peu cohérent

Les fonc­tions min et max retournent res­pec­ti­ve­ment le mini­mum et le maxi­mum d'une série de nombres :

Jusque là, tout va bien. La fonc­tion mean est uti­li­sée pour trou­ver la moyenne :

… Je pense que R devrait prendre quelques leçons de sta­tis­tiques.

Sait-il cal­cu­ler une médiane ?

Appa­rem­ment pas, mais au moins nous signale-t-il gen­ti­ment que quelque chose ne tourne pas rond.

Mais pourquoi donc ?

En fait, il vaut mieux uti­li­ser ces fonc­tions sur des vec­teurs, ce que tout le monde fait en pra­tique :

Notez tout de même que dans le pre­mier cas, la fonc­tion mean :

  • ne retourne pas d’erreur.
  • ne retourne pas de war­ning.
  • retourne un résul­tat (faux) du type atten­du (un nombre).

Quel machia­vé­lisme ! Si l'utilisateur ne teste pas rigou­reu­se­ment son code, il court droit à la catas­trophe.

Le facteur numérique accidentel

Ima­gi­nons, par exemple, qu'un inno­cent vec­teur numé­rique se retrouve par mégarde sous la forme d'un fac­tor (par exemple, suite à une facé­tie des célèbres fonc­tions read.table ou data.frame, et de leur non moins célèbre para­mètre string­sAs­Fac­tor dont la valeur par défaut est à l'origine de la majo­ri­té de mes bugs R). L'utilisateur aver­ti pour­rait se dire en toute confiance : "Pas de panique, je connais la fonc­tion as.numeric".

Qui aurait pu ima­gi­ner qu'un tel désastre était immi­nent ?

Haha ! Je connais la fonc­tion as.numeric ! (cli­quez sur l'image)

Mais pourquoi donc ?

as.numeric ne fonc­tionne pas comme vous le pen­sez sur les fac­tors :

Du coup, il faut pas­ser par un p'tit coup de as.character :

Ou alors, si vous êtes pédant :

L'arrondi du coin

Par­fois, il est bien utile d’arrondir un peu tous ces nombres com­pli­qués avec plein de vir­gules. La fonc­tion round fait, en géné­ral, assez bien son tra­vail :

Il y a tou­jours cette petite hési­ta­tion quant à savoir com­ment sera arron­di 0.5, en 0 ou en 1 ?

OK. R fait donc par­tie de ces lan­gages qui arron­dissent X.5 à l'entier infé­rieur. Pour­quoi pas. Ce n'est pas ce qu'on m'a appris à l'école, mais bon, pour­quoi pas ?

Hein ?! Mais R enfin, qu'est-ce que tu fais ? C'est trop te deman­der d’être cohé­rent pen­dant deux lignes ?

♪♫ Lala­la ♫♪ Je suis R. Je fais ce que je veux. ♪♫ Lala­la ♫♪ J’arrondis X.5 à l'entier pair le plus proche si je veux. ♪♫ Lala­la ♫♪

R

Mais pourquoi donc ?

Si on arron­dit un grand échan­tillon­nage de…
Si on réflé­chit bien, on s’aperçoit que…
…poten­tiel biais dans…
Et bien en fait…
Les auteurs de R ont…

Heu, bon, pas­sons.

Une matrice dans un tableau

Il est pos­sible d'inclure une matrix comme colonne d'un data.frame. Com­pa­rez donc :

Mais pourquoi ?

You will sur­ely think that allo­wing a data.frame to have com­po­nents with more than one column is an abo­mi­na­tion. That will be your thin­king unless, of course, you’ve had occa­sion to see it being use­ful.

Patrick Burns

Vous pen­se­rez sûre­ment qu'autoriser des com­po­sants de plus d'une colonne dans un data.frame est une abo­mi­na­tion. Vous pen­se­rez cela, à moins bien sûr que vous n'ayez eu l'occasion de voir cela mis en pra­tique de façon utile.

L’échantillonnage approximatif

La fonc­tion sample est bien pra­tique pour échan­tillon­ner au hasard un vec­teur, avec ou sans remise :

Le pro­gram­meur expé­ri­men­té se dira que ce bout de code a l'air dan­ge­reux dans le cas où myVect est vide. En effet, mais R a la décence de nous pré­ve­nir :

Le cas où myVect ne contient qu'un unique élé­ment semble bien moins pro­blé­ma­tique (haha­ha ! Bande de naïfs) :

Notez bien :

  • Pas de mes­sage d’erreur.
  • Pas de war­ning.
  • Un résul­tat sous la forme de 5 nombres, comme atten­du.

Pour­tant, ce n'était peux-être pas ce que vous dési­riez. Je blê­mis à l'idée du nombre de bugs non réso­lus cau­sés par ce petit twist.

Mais pourquoi ?

Dans cer­tains cas, c'est bien pra­tique de pou­voir faire sample(100, 5) et d'obtenir :

R se montre com­pré­hen­sif, et essaye de nous pré­ve­nir dans les petites lignes de bas de page du manuel :

If x has length 1, is nume­ric (in the sense of is.numeric) and x >= 1, sam­pling via sample takes place from 1:x. Note that this conve­nience fea­ture may lead to unde­si­red beha­viour when x is of varying length in calls such as sample(x).

Si x a une lon­gueur de 1, est numé­rique (tel que défi­ni paris.numeric) etx >= 1, l’échantillonnage via sample a lieu sur 1:x. Notez bien que cette carac­té­ris­tique peut abou­tir à un com­por­te­ment indé­si­ré lorsque la lon­gueur de x varie lors d'appels tels que sample(x).

Noitaréti à l'envers

Si vous essayez d'écrire en douce une petite boucle

for, comme ça, ni vu ni connu (en géné­ral, quand on est pédant et qu'on fait du R, on pré­fère faire de la pro­gram­ma­tion fonc­tion­nelle) (mais sinon, les boucles for ont la répu­ta­tion d'être lentes en R. C'est assez faux. Elles ne sont pas plus lentes que le reste, du moment que vous ne faîtes pas gran­dir des objets dedans. Pen­sez à pré-allouer le résul­tat) (mais repre­nons) :

Que se passe-t-il si myTable est vide ?

Une suc­ces­sion d'événements inat­ten­due

Mais pourquoi ?

Et oui, nrow(myTable)vaut 0, et 1:0 retourne

Ça alors, c'est pas de chance ! Pré­fé­rez donc seq_len(nrow(myTable)).

Javascript, sort de ce coRps !

Mais pourquoi ?

Le message d’erreur le plus utile du monde

Mais pourquoi ?

If you aren’t expec­ting 'else' in "else", then where would you expect it ?
While you may think that R is ludi­crous for giving you such an error mes­sage, R thinks you are even more ludi­crous for expec­ting what you did to work.

Patrick Burns

Si tu ne t’attends pas à un 'else' dans "else", où donc t'attends-tu à en voir un, R ?
Vous pen­se­rez peut-être que c'est ridi­cule pour R de retour­ner un tel mes­sage d'erreur. R pense que vous êtes encore plus ridi­cule d’espérer que ce que vous aviez fait fonc­tion­ne­rait.

En vrac

  • La fonc­tion read.table retourne un data.frame, et pas une table.
  • La fonc­tion table retourne une table.
  • La fonc­tion sort.list ne sert pas à trier les listes.
  • > seq(5:10)
  • [1] 1 2 3 4 5 6

(╯°□°)╯︵ ┻━┻

Bonus

Votre col­lègue s'est absen­té en lais­sant sa ses­sion R ouverte ? Pro­fi­tez-en, soyez infer­nal ! Voi­ci quelques petites com­mandes amu­santes à taper dans sa ses­sion :

Le petit mot de fin

Tout ceci décrit le com­por­te­ment de R 3.3.1. Il est pos­sible que cer­taines inco­hé­rences soient réso­lues dans les pro­chaines ver­sions. Cela me semble assez peu pro­bable cepen­dant, pour des rai­sons de rétro-com­pa­ti­bi­li­té.
Vous ne l'aurez peut-être pas com­pris, mais ce n'est aucu­ne­ment un article à charge. Il s'agit juste d'une mise en pra­tique de l’adage "qui aime bien châ­tie bien".
Si vous en rede­man­dez, n'hésitez pas à remon­ter ma source : The R Infer­no !

Mer­ci à mes talen­tueux relec­teurs Beba­tut, Cho­po­pope, Estel et Lroy !




Commentaires

14 réponses à “C'est l'enfeR.”

  1. Avatar de GrumpyStat

    Bon­jour,

    Alors je veux bien admettre qu'il y a quelques sou­cis avec R mais là vous pous­sez le bou­chon très loin. La moi­tié de vos "sur­prise" vient de ce que vous n'avez pas lu le manuel avant d'utiliser une com­mande (typi­que­ment, la fonc­tion agit dif­fé­rent sur un vec­teur que sur des nombre ren­trés direc­te­ment). Fran­che­ment pas de quoi crier au loup quand c'est dit expli­ci­te­ment dans le manuel.

    Le round a une logique, oui. Par exemple, si vous faites la moyenne de 0.5 1.5 2.5 3.5 4.5 vous obte­nez 2.5 et de round de cette liste vous obte­nez 2.4 avec R. Alors que si vous aviez un "floor" au lieu de ça (l'entier du des­sous) ben vous avez une moyenne de 2 ! Alors oui ça fait une belle dif­fé­rence quand on traite des échan­tillons, et c'est plu­tôt malin.

    Mais bien plus grave, votre "erreur inutile"

    > i if (i == pi) message("pi!")
    > else message("papi!")
    Error : unex­pec­ted 'else' in "else"

    vient sim­ple­ment du fait que vous avez tapé "entrer" avant d'entrer la com­mande else. Si on finit une com­mande, R va pas devi­ner tout seul qu'en fait il fal­lait attendre la suite avant d'interpréter le "if". Donc la, lui il ne voit que un "else" sans un "if".
    Faites l'essaie :

    > if (i == pi) message("pi!") else message("papi")
    papi

    A bon enten­deur !

    1. Ce n'est pas parce qu'il y a une logique que c'est jus­ti­fié ; INTERCAL suit une logique impa­rable, et si on ne l'utilise pas (au-delà du fait qu'il s'agit d'un pur lan­gage éso­té­rique),
      c'est parce que cette logique ne per­met pas de tra­vailler dans des condi­tions mini­male d'hygiène men­tale, c'est-à-dire avec un niveau d’abstraction suf­fi­sant.

      R, tel que je l'ai vu durant mes quelques heures d'utilisation, et tel que je le vois là, est un gre­nier de com­por­te­ments mal abs­traits.
      L'abstraction est une bonne chose quand elle est bien faite, et de toute évi­dence ce n'est pas le cas dans R.

      J'imagine qu'il est pos­sible de pas­ser outre tous ces pro­blèmes, en ajoutant/​modifiant légè­re­ment le code. Mais cela néces­site le déve­lop­pe­ment d'une exper­tise qui devient un frein à la fois quand il s'agit de faire apprendre le lan­gage, mais aus­si lors de son usage.
      A‑ton vrai­ment envie d'avoir un tel coût d'exploitation pour ce qui ne doit res­ter qu'un outils ?

      C'est selon moi la dif­fé­rence entre un « bon » lan­gage et un « mau­vais » lan­gage,

      (indé­pen­dam­ment de toute notion d'outils rat­ta­ché au lan­gage,
      python serais bien moins brillant sans pip, et C++ moins inté­res­sants sans boost)

      Un exemple de cette oppo­si­tion, c'est COBOL et Ada.
      Le pre­mier est un lan­gage dif­fi­cile parce qu'il est, dans un registre un peu dif­fé­rent de R, com­plexe à l'usage et à la main­te­nance.
      Le second est com­plexe éga­le­ment, mais pour une rai­son beau­coup plus saine : Ada aborde la notion d'orienté objet avec une approche dif­fé­rente des lan­gages plus habi­tuels (c++, java).

      L'un et l'autre des lan­gages ont un coups d'apprentissage consé­quent, mais l'un des deux demande la com­pré­hen­sion d'un para­digme, là où l'autre demande la com­pré­hen­sion de détails d'implémentation, d'effets de bords et de com­por­te­ments.

      En clair, quand vous appre­nez Ada, vous ne per­dez pas votre temps sur le lan­gage, mais sur la concep­tion. Ce qui est réuti­li­sable par­tout, et une fois acquis, tota­le­ment trans­pa­rent.

      C'est l'inverse pour R. On perd du temps et de l'énergie avec ce lan­gage, même après appren­tis­sage, alors que tout ce dont on a besoin, c'est d'un outils de haut niveau pour étu­dier les don­nées. Et tout le monde perd ce temps. Même les experts doivent pen­ser en per­ma­nences à ces détails, et,
      plu­tôt que mani­pu­ler abs­trai­te­ment leurs don­nées, sont en per­ma­nence en train de com­pen­ser le lan­gage.

      Que round ait un com­por­te­ment bizarre est une chose (même les roun­ding qui suivent la norme IEEE font par­fois des sur­prises), mais que ce genre d'abstraction mal fichue soit aus­si répan­du dans la base de code, c'est la marque d'un lan­gage « bro­ken by desi­gn ».
      Ça donne l'impression un lan­gage patché/​développé dans tous les sens, sans cohé­rence glo­bale, qui n'est pas sans rap­pe­ler PHP ou javas­cript.

      Certes, comme pour PHP, R pro­pose une doc consé­quente…
      Mais ce n'est pas suf­fi­sant pour jus­ti­fier une mau­vaise abs­trac­tion !

      « oui, je sais, ma méthode to_​int ren­vois une string, mais je l'ai expli­qué dans la doc ! Tout va bien !».

      En somme, ce sont des lan­gages dont la seule véri­table fea­ture est l'absence d'alternative.

      (en fait, elles existent, mais sont trop peu utilisées/​matures)

      Pour don­ner des exemples de ce que je consi­dère comme de « bon » lan­gages, et pour­quoi ils le sont, il y a Ada, mais aus­si Python, Has­kell, et bien d'autres.
      Ces lan­gages ne réus­sissent pas pour la même rai­son.
      Pour Ada, c'est des impé­ra­tifs pro­fes­sion­nels qui néces­sitent que le lan­gage soit au top.
      Pour Python, c'est un BDFL com­pé­tent et cohé­rent.
      Pour Has­kell, c'est le pari d'implémenter à fond un para­digme.

      Ils ne sont évi­dem­ment pas exempts de (ter­ribles) défauts, mais s'ils n'en ont pas autant que R, PHP et javas­cript, c'est pro­ba­ble­ment pas un hasard.

      Quelques liens :

      - PHP : https://​secure​.pha​bri​ca​tor​.com/​b​o​o​k​/​p​h​a​b​f​l​a​v​o​r​/​a​r​t​i​c​l​e​/​p​h​p​_​p​i​t​f​a​l​ls/
      — Python : http://​sta​cko​ver​flow​.com/​q​u​e​s​t​i​o​n​s​/​5​3​0​5​3​0​/​p​y​t​h​o​n​-​2​-​x​-​g​o​t​c​h​a​s​-​a​n​d​-​l​a​n​d​m​i​nes
      — INTERCAL : https://​en​.wiki​pe​dia​.org/​w​i​k​i​/​I​N​T​E​R​CAL

      Et, comme je suis très orien­té python et que moi aus­si, je défends, objec­ti­ve­ment n'est-ce pas, mon bout de gras : http://​mecha​ni​cal​cat​.net/​c​g​i​-​b​i​n​/​l​o​g​/​p​y​t​h​o​n​/​a​n​t​i​-​p​i​t​f​a​l​l​s​.​h​tml

      1. Avatar de GrumpyStat

        Je suis plu­tôt d'accord avec vous sur les fai­blesses de R en tant que lan­gage de pro­gram­ma­tion, étant plu­tôt C++ que R moi-même.
        C'est la fai­blesse des argu­ment de ce blog­post qui m'a remon­tée. Typi­que­ment, il aurait été inté­res­sant de pous­ser plus loin les com­por­te­ments étranges de R (i.e. pour­quoi ils existent), que de se conten­ter de taper sur 2–3 exemples bidons qui ne sur­pren­dra pas n'importe quel uti­li­sa­teur régu­lier de R. Pour n'importe quel autre lan­gage il serait facile de trou­ver des exemples simi­laires.

        1. "Pour n'importe quel autre lan­gage il serait facile de trou­ver des exemples simi­laires."
          Pas si sûr, R est un très bon can­di­dat quand même 🙂
          Sinon il y a javas­cript qui est connu pour être du grand n'importe quoi (d'où le nombre incroyable de librai­ries (jque­ry, angu­lar…) qui en sont sor­tie car il reste très pra­tique) 🙂

          Sinon pour C++ et boost, j'avais bien aimé l'avis de notre ami Linus :
          http://harmful.cat‑v.org/software/c++/linus

          Ahah

  2. Fran­che­ment pas de quoi crier au loup quand c'est dit expli­ci­te­ment dans le manuel

    Ce n'est pas vrai­ment un bon argu­ment. Si je crée un lan­gage où il faut mettre un else avant le if, et où le "==" teste une inéga­li­té, mais que je mets tout ça dans le manuel, est-ce que ça ne serait pas un pro­blème de cohé­rence pour autant ? Dans un bon lan­gage, tout ce qui est à même de trom­per l'utilisateur lamb­da est à évi­ter, sinon le lan­gage peut être effec­ti­ve­ment qua­li­fié d'ésotérique.

    Par exemple, si vous faites la moyenne de 0.5 1.5 2.5 3.5 4.5 vous obte­nez 2.5 et de round de cette liste vous obte­nez 2.4 avec R. Alors que si vous aviez un "floor" au lieu de ça (l'entier du des­sous) ben vous avez une moyenne de 2 ! Alors oui ça fait une belle dif­fé­rence quand on traite des échan­tillons, et c'est plu­tôt malin.

    Per­son­nel­le­ment je trouve qu'arrondir un vec­teur avant d'en faire la moyenne est une aber­ra­tion sta­tis­tique. Je ne vois pas non plus en quoi avoir une moyenne de 2.4 est mieux qu'avoir une moyenne de 2. Pour­quoi est-ce qu'on s'attendrait à ce que l'arrondi conserve une moyenne non arron­die ? Le com­por­te­ment du floor est bien plus cohé­rent (la moyenne de l'arrondi est égale à l'arrondi de la moyenne).

    Mais bien plus grave, votre "erreur inutile"

    On est d'accord, il y a bien une erreur et R le signale. Le pro­blème n'est pas là. Le pro­blème c'est que le mes­sage d'erreur est là pour se foutre de la gueule de l'utilisateur, et est com­plè­te­ment non infor­ma­tif. En gros, ça cor­res­pond bien au fait que R est un lan­gage écrit par des trolls et pour des trolls 🙂 .

  3. Mon hon­nête me pousse à défendre R, et cela en éton­ne­ra cer­tain.

    Le pre­mier point, qui concerne les éga­li­tés de nombre flot­tant, est en fait com­mun a presque tous les lan­gages je dis presque car je n'est pas véri­fié tous les lan­gages. Le pro­blème est inhé­rent a com­ment on repré­sente un nombre en vir­gule flot­tant et com­ment on réa­lise une com­pa­rai­son. En fait R ne fait ni mieux ni moins bien que les autres lan­gages.

    Un autre point quel que peu ban­cale et la com­pa­rai­son entre les nombres et les chaines de carac­tère. Ce pro­blème vient du faite que R est un lan­gage a typage faible (comme le javas­cript mais ce n'est pas le seul), quand on réa­lise une opé­ra­tion entre deux type dif­fé­rent le lan­gage tente de conver­tir l'un des types en l'autre. Pro­blème cette conver­sion ce fait sou­vent silen­cieu­se­ment (même pas un petit war­ning) et pas comme on le crois ins­tinc­ti­ve­ment. Encore une fois R n'est pas pire mais cer­tai­ne­ment pas meilleur que les autres.

    Sur le fond je suis tout a fait d'accord R est l'un des pires lan­gages qui existe mais ces deux argu­ments sont faibles.

    Bisous

    Ps : vive python et pan­da

  4. Per­son­nel­le­ment l'article m'a bien fait rire 🙂
    Ensuite je par­tage com­plé­te­ment le com­men­taire de Lucas (et les orien­ta­tions pro­gram­mis­tiques ^^).

    Je rajoute d'ailleurs un petit lien infor­ma­tif sur quelques bizar­re­ries du coté de python his­toire de prou­ver ma bonne foi : https://​access​.red​hat​.com/​b​l​o​g​s​/​7​6​6​0​9​3​/​p​o​s​t​s​/​2​5​9​2​591

    Mer­ci encore @ Guillaume pour l'article !

  5. Vue que cette article parle sur­tout d'incohérence et de chose étrange dans les lan­gages de pro­gram­ma­tion je vous invite a lire ce file sta­cko­ver­flow https://​sta​cko​ver​flow​.com/​q​u​e​s​t​i​o​n​s​/​1​9​9​5​1​1​3​/​s​t​r​a​n​g​e​s​t​-​l​a​n​g​u​a​g​e​-​f​e​a​t​ure

    On y trouve de nom­breuse chose amu­sante lou­foque ou même stu­pide.

  6. Une petite pré­ci­sion concer­nant ce pas­sage :

    > Le pro­blème des nombres à vir­gule, c'est que la par­tie après la vir­gule peut être infi­nie, alors que la mémoire des ordi­na­teurs ne l'est pas. Du coup, les ordi­na­teurs décident plu­tôt de ne gar­der que quelques (dizaines de) nombres après la vir­gule, et d'oublier les autres. Ils font donc plein de petites erreurs de cal­cul débiles

    On pour­rait s'étonner que 0.1 pose pro­blème car il n'a appa­rem­ment pas un nombre infi­ni de chiffres après la vir­gule. En fait si je me sou­viens bien de mes cours d'info, c'est sa décom­po­si­tion en somme de puis­sances de 2 qui néces­si­te­rait un nombre infi­ni de puis­sances de 2 (néga­tives, ici) pour repré­sen­ter sa valeur exacte.

    À pro­pos des dif­fi­cul­tés que pose R, hier même, dans un moment de frus­tra­tion j'ai cher­ché du récon­fort sur l'internet en cher­chant "Why I hate R", et je suis tom­bé sur cet article qui me semble assez juste :
    http://www.talyarkoni.org/blog/2012/06/08/r‑the-master-troll-of-statistical-languages/

    Résu­mé sim­pli­fié : L'article dit que dès qu'on cherche à faire le malin avec R, on se fait en géné­ral avoir, à moins d'être vrai­ment super au point.

  7. Ah, ben je vois que l'article que je men­tionne était en fait cité dès juste après le pas­sage auquel je réagis­sais. Ça m'apprendra à réagir avant d'avoir tout lu.

  8. R m'a de nou­veau mor­du. Un autre cas de com­por­te­ment appa­rem­ment inco­hé­rent de R : http://​sta​cko​ver​flow​.com/​q​u​e​s​t​i​o​n​s​/​4​0​8​6​7​703

  9. L'article date un peu, et même si je com­prends tout à fait le ton humo­ris­tique du conte­nu, la qua­si tota­li­té des "inco­hé­rences" pré­sen­tées ici ne le sont pas :

    "R ne sait pas cal­cu­ler" : bah oui mais si on com­prend un peu com­ment sont enco­dés les flot­tants, on se dit vite que c'est presque nor­mal (et sur­tout, pas propre à R)
    "R est en moyenne assez peu cohé­rent" : sauf que pour le coup, c'est l'exemple qui est inco­hé­rent. mean() c'est une fonc­tion, qui prend plu­sieurs argu­ments. mean(x,y,z) fait la moyenne de l'objet X ; donc for­cé­ment si tu lui passes mean(-1,5,118) il fait la moyenne sur ‑1, c'est pas si cho­quant après tout. [Et sur median, qui ne prend que 2 argu­ments, l'erreur est pour­tant très claire]
    "Le fac­teur numé­rique acci­den­tel" : sauf qu'en fait, y a aucune rai­son pour que tes fac­teurs soient consi­dé­rés comme des nombres, donc la méthode as.numeric() sur fac­teurs, ça ren­voie le numé­ro du niveau, en toute logique.
    "L'arrondi du coin" : c'est un stan­dard, il porte même un chouette nom : IEC 60559
    "Une matrice dans un tableau" : l'exemple est sym­pa, mais pas pour l'incohérence que l'auteur pointe, parce qu'il ne fait pas la dif­fé­rence entre "=" et "<-" et pour­tant la dif­fé­rence est grande !
    "L’échantillonnage approxi­ma­tif" : bon je reviens pas des­sus, l'auteur l'explique très bien
    "Noi­ta­ri­té à l'envers" : c'est ce qu'on appelle la décré­men­ta­tion, on ne va quand même pas repro­cher à R de com­prendre tout seul (c'est à dire sans avoir besoin de lui dire –i au lieu de ++i) que pour pas­ser de 1 à 0 il doit décré­men­ter, si ?
    -"JS sors de ce corps" : l'incohérence c'est de vou­loir com­pa­rer deux types dif­fé­rents entre eux, pas tel­le­ment la réponse qui ici dépend juste du terme qui sera conver­ti
    "Le mes­sage d'erreur le plus utile du monde" : il me paraît pour­tant lim­pide ce mes­sage, tu tra­vailles en consoles, tes lignes de codes sont indé­pen­dantes si tu tape entrée, donc for­cé­ment le else se retrouve sans if et bah ça n'est pas pos­sible quoi… (la pro­chaine fois suf­fit d'essayer shift+entrée :))
    "En vrac" : read.table et sort.list on est d'accord c'est drôle ; en revanche seq() bah même remarque que pour mean(), faut com­prendre ce qu'est une fonc­tion et un argu­ment
    "Bonus" : j'adore, j'y pen­se­rai 😀

    Sinon, l'article est sym­pa (tout comme le livre duquel il s'inspire d'ailleurs), je com­prends son uti­li­té et sai­si le ton humo­ris­tique, R est en effet un lan­gage… sur­pre­nant, et par­fois dif­fi­cile à appré­hen­der voir contre intui­tif (cepen­dant pas sur les exemples repris ci-des­sus, en fait), Mais il faut le prendre comme il l'est, le petit, non pas un lan­gage de pro­gram­ma­tion des­ti­né à coder tout et n'importe quoi mais un lan­gage avec visu inté­gré pour faire de l'analyse de don­nées sym­pa­toche.

    1. Hmm, com­men­taire par­ti trop vite, je refor­mule ma der­nière phrase mal construite :

      << Mais il faut le prendre comme il est, non pas un lan­gage de pro­gram­ma­tion des­ti­né à coder tout et n'importe quoi mais un ensemble de fonc­tions ad hoc avec visua­li­sa­tion inté­grée pour faire de l'analyse de don­nées >>
      serait plus cor­rect !

Laisser un commentaire