30 votes

Désactiver l'affectation via = dans R

R permet de cession via <- et =.

Alors qu'il y a des différences subtiles entre les deux opérateurs d'affectation, il semble y avoir un large consensus <- est le meilleur choix que l' =, comme = est également utilisé comme opérateur de cartographie des valeurs des arguments, et donc son utilisation peut conduire à des déclarations ambiguës. La suite de l'illustre bien:

> system.time(x <- rnorm(10))
   user  system elapsed 
      0       0       0 
> system.time(x = rnorm(10))
Error in system.time(x = rnorm(10)) : unused argument(s) (x = rnorm(10))

En fait, le Google code interdit l'utilisation de = pour l'affectation (voir les commentaires relatifs à cette réponse pour un converse de la vue).

J'ai aussi presque exclusivement utiliser <- comme opérateur d'affectation. Cependant, le presque dans la phrase précédente est la raison pour laquelle cette question. Lors de l' = agit comme opérateur d'affectation dans mon code, il est toujours accidentelle et si elle conduit à des problèmes de ces sont généralement difficiles à repérer.

Je voudrais savoir si il existe un moyen de désactiver l'affectation via = et soit R jeter une erreur tout moment, = est utilisé pour l'affectation.

De façon optimale, ce comportement ne se produit que pendant le code de l'Environnement Mondial, comme il peut y avoir de code ci-jointe espaces de noms qui utilise = pour l'affectation et ne doit pas se briser.

(Cette question a été inspiré par une discussion avec Jonathan Nelson)

36voto

James Points 24725

Voici un candidat:

 `=` <- function(...) stop("Assignment by = disabled, use <- instead")
# seems to work
a = 1
Error in a = 1 : Assignment by = disabled, use <- instead
# appears not to break named arguments
sum(1:2,na.rm=TRUE)
[1] 3
 

9voto

MvG Points 22342

Je ne suis pas sûr, mais peut-être simplement écraser l'affectation de = vous suffit. Après tout, `=` est un nom comme un autre, presque.

 > `=` <- function() { }
> a = 3
Error in a = 3 : unused argument(s) (a, 3)
> a <- 3
> data.frame(a = 3)
  a
1 3
 

Ainsi, toute utilisation de = pour l'affectation entraînera une erreur, tandis que son utilisation pour nommer les arguments reste valide. Son utilisation dans les fonctions peut passer inaperçue à moins que la ligne en question ne soit réellement exécutée.

7voto

flodel Points 41487

L' lint package (CRAN) a un style de vérifier que, donc, en supposant que vous avez votre code dans un fichier, vous pouvez exécuter les peluches contre lui et qu'il va vous avertir au sujet de ces numéros de ligne avec = devoirs.

Voici un exemple de base:

temp <- tempfile()
write("foo = function(...) {
          good <- 0
          bad = 1
          sum(..., na.rm = TRUE)
       }", file = temp)

library(lint) 
lint(file = temp, style = list(styles.assignment.noeq))
# Lint checking: C:\Users\flodel\AppData\Local\Temp\RtmpwF3pZ6\file19ac3b66b81
# Lint: Equal sign assignemnts: found on lines 1, 3

L' lint paquet vient avec un peu plus de tests que vous pouvez trouver intéressant, y compris:

  • met en garde contre le droit des affectations
  • recommande des espaces autour =
  • recommande des espaces après les virgules
  • recommande que les espaces entre les suffixes (un.k.un. opérateurs binaires)
  • met en garde contre les onglets
  • possibilité de mettre en garde contre un max de largeur de ligne
  • met en garde contre les affectations à l'intérieur des appels de fonction

Vous pouvez l'activer ou la désactiver à tout de la pré-défini les chèques de style et vous pouvez écrire votre propre. Cependant, le paquet est encore à ses balbutiements: il est livré avec quelques bugs (https://github.com/halpo/lint), et la documentation est un peu dur à digérer. L'auteur est sensible, bien que lentement, à apporter des améliorations.

3voto

mnel Points 48160

Si vous ne voulez pas casser le code existant, quelque chose comme ceci (l'impression d'un avertissement, pas une erreur) pourrait fonctionner - vous donner l'alerte alors attribuer à l' parent.frame l'aide <- (à éviter tout de récursivité)

`=` <- function(...){
        .what <- as.list(match.call())
        .call <-  sprintf('%s <- %s', deparse(.what[[2]]),  deparse(.what[[3]]))
        mess <- 'Use <- instead of = for assigment '
        if(getOption('warn_assign', default = T)) {
        stop (mess) } else {
        warning(mess)
        eval(parse(text =.call), envir = parent.frame())  
          }
        }

Si vous définissez options(warn_assign = F), alors = pour les avertir et de les céder. Tout le reste sera de jeter une erreur et de ne pas céder.

exemples d'utilisation

# with no option set
z = 1
## Error in z = 1 : Use <- instead of = for assigment 
options(warn_assign = T)
z = 1
## Error in z = 1 : Use <- instead of = for assigment 
 options(warn_assign = F)
 z = 1
## Warning message:
##  In z = 1 : Use <- instead of = for assigment 

De meilleures options

Je pense que formatR ou lint et de formatage de code sont les meilleures approches.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X