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.