R: + = (plus égal) et ++ (plus plus) équivalent de c ++ / c # / java, etc.?


Réponses:



64

Après @ GregaKešpret, vous pouvez créer un opérateur d'infixe:

`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x

6
(+1), mais un mot d'avertissement. La frappe x = %+=% y/2revient x = (x + y)/2. L'ajout de parenthèses, c'est-à-dire x = %+=% (y/2)résout le problème.
knrumsey

@knrumsey Pourquoi est-ce? J'aurais supposé que la division serait un opérateur de priorité plus élevée.
David Kelley

@DavidKelley Pas sûr. Je suis avec toi là-bas. J'ai rencontré ce problème en travaillant sur un projet une fois et il m'a fallu une heure pour trouver le problème.
knrumsey

N'oubliez pas que vous exécutez une fonction, pas une addition. Les fonctions ont la priorité la plus élevée, donc sans la parenthèse, elle analyse le y comme entrée de fonction, la division étant l'étape suivante dans la chaîne. La parenthèse élève l'opération (y / 2) en haut de la chaîne.
Justin

33

R n'a pas de concept de increment operator(comme par exemple ++ en C). Cependant, il n'est pas difficile d'en implémenter un vous-même, par exemple:

inc <- function(x)
{
 eval.parent(substitute(x <- x + 1))
}

Dans ce cas, vous appelleriez

x <- 10
inc(x)

Cependant, cela introduit une surcharge d'appel de fonction, donc c'est plus lent que de taper x <- x + 1vous-même. Si je ne me trompe pas, il a increment operatorété introduit pour faciliter le travail du compilateur, car il pourrait convertir directement le code en ces instructions en langage machine.


3
Cette fonction ne peut pas retourner la valeur puis incrémenter comme un postincrement ++. C'est plus similaire à + = ou preincrement ++.
Megatron

Faux! L'incrémentation n'a pas été introduite pour faciliter le travail du compilateur. INCL'instruction a été introduite dans les processeurs principalement pour l'implémentation des compteurs (cf. Manuel du développeur de logiciels Intel). Je mettrai à jour la réponse.
banan3'14

19

R n'a pas ces opérations car (la plupart) des objets dans R sont immuables. Ils ne changent pas. En règle générale, lorsqu'il semble que vous modifiez un objet, vous modifiez en fait une copie.


18
Bien que l'immuabilité soit une propriété intéressante / souhaitable pour les objets (lire: moins de bogues), je ne pense pas que l'immutabilité soit liée à la question + =. Dans d'autres langages, + = peut être appliqué à des types immuables (comme des chaînes dans .net). L'opération crée simplement un nouvel objet et affecte la variable donnée à ce nouvel objet. L'immuabilité est maintenue et la variable est mise à jour.
SFun28

4
Bon point. Cependant, l'immuabilité rend certainement ce genre d'opération moins naturel.
hadley

15

Incrémenter et décrémenter de 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10

7
Ces fonctions semblent avoir été supprimées depuis la Hmiscversion 4.1.0.
llasram

@llasram en regardant cette notation, je ne peux blâmer personne.
bers


3

Nous pouvons passer outre +. Si unaire +est utilisé et que son argument est lui-même un +appel unaire , incrémentez la variable appropriée dans l'environnement appelant.

`+` <- function(e1,e2){
    # if unary `+`, keep original behavior
    if(missing(e2)) {
      s_e1 <- substitute(e1)
      # if e1 (the argument of unary +) is itself an unary `+` operation
      if(length(s_e1) == 2 && 
         identical(s_e1[[1]], quote(`+`)) && 
         length(s_e1[[2]]) == 1){
        # increment value in parent environment
        eval.parent(substitute(e1 <- e1 + 1,list(e1 = s_e1[[2]])))
      # else unary `+` should just return it's input
      } else e1
    # if binary `+`, keep original behavior
    } else .Primitive("+")(e1,e2)
}

x <- 10
++x
x
# [1] 11

les autres opérations ne changent pas:

x + 2
# [1] 13
x ++ 2
# [1] 13
+x
# [1] 11
x
# [1] 11

Ne le faites pas car vous ralentirez tout. Ou faites-le dans un autre environnement et assurez-vous de ne pas avoir de grandes boucles sur ces instructions.

Vous pouvez également simplement faire ceci:

`++` <- function(x) eval.parent(substitute(x <-x +1))
a <- 1
`++`(a)
a
# [1] 2

-1

Il y a une autre façon de faire cela, que je trouve très facile, peut-être que cela pourrait vous aider

J'utilise <<-pour ces situations Les opérateurs <<-attribuent la valeur à l'environnement parent

inc <- function(x)
{
   x <<- x + 1
}

et vous pouvez l'appeler comme

x <- 0
inc(x)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.