R: + = (más igual) y ++ (más más) equivalente de c ++ / c # / java, etc.

Respuestas:

64

Siguiendo @ GregaKešpret puedes hacer un operador infijo:

`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x
bautista
fuente
66
(+1), pero una palabra de advertencia. Mecanografía x = %+=% y/2vuelve x = (x + y)/2. Agregar paréntesis, es decir, x = %+=% (y/2)resuelve el problema.
knrumsey
@knrumsey ¿Por qué es eso? Supuse que la división sería un operador de mayor prioridad.
David Kelley
@DavidKelley No estoy seguro. Estoy contigo allí. Me encontré con este problema trabajando en un proyecto una vez y me llevó una hora encontrarlo.
knrumsey
Recuerde que está ejecutando una función, no haciendo una adición. Las funciones tienen la mayor prioridad, por lo que sin el paréntesis analiza la y como la entrada de la función, siendo la división el siguiente paso en la cadena. El paréntesis eleva la operación (y / 2) a la parte superior de la cadena.
Justin
33

R no tiene un concepto de increment operator(como por ejemplo ++ en C). Sin embargo, no es difícil implementar uno usted mismo, por ejemplo:

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

En ese caso llamarías

x <- 10
inc(x)

Sin embargo, presenta una sobrecarga de llamadas de función, por lo que es más lento que escribir x <- x + 1usted mismo. Si no me equivoco, increment operatorse introdujo para facilitar el trabajo del compilador, ya que podría convertir el código a esas instrucciones de lenguaje de máquina directamente.

Grega Kešpret
fuente
3
Esta función no puede devolver el valor y luego aumentar como un postincremento ++. Es más similar a + = o preincrement ++.
Megatron
¡Incorrecto! El aumento no se introdujo para facilitar el trabajo del compilador. INCla instrucción se introdujo en procesadores principalmente para implementar contadores (véase el Manual del desarrollador de software de Intel). Actualizaré la respuesta.
banan3'14
19

R no tiene estas operaciones porque (la mayoría) de los objetos en R son inmutables. No cambian Por lo general, cuando parece que está modificando un objeto, en realidad está modificando una copia.

Hadley
fuente
18
Si bien la inmutabilidad es una propiedad excelente / deseable para los objetos (léase: menos errores), no creo que la inmutabilidad se relacione con la pregunta + =. En otros idiomas, + = se puede aplicar a tipos inmutables (como cadenas en .net). La operación simplemente crea un nuevo objeto y asigna la variable dada a ese nuevo objeto. La inmutabilidad se mantiene y la variable se actualiza.
SFun28
44
Buen punto. Sin embargo, la inmutabilidad ciertamente hace que este tipo de operación sea menos natural.
hadley
15

Incremento y decremento en 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10
Vagabundo
fuente
77
Estas funciones parecen haberse eliminado a partir Hmiscde la versión 4.1.0.
llasram
@llasram mirando esa notación, no puedo culpar a nadie.
bers
3

Podemos anular +. Si +se usa unario y su argumento es en sí mismo una +llamada unaria , entonces incremente la variable relevante en el entorno de llamada.

`+` <- 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

otras operaciones no cambian:

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

Sin embargo, no lo hagas, ya que ralentizarás todo. O hágalo en otro entorno y asegúrese de no tener grandes bucles en estas instrucciones.

También puedes hacer esto:

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

Hay otra forma de hacer esto, que me parece muy fácil, tal vez podría ser de alguna ayuda

Utilizo <<-para esta situación Los operadores <<-asignan el valor al entorno principal

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

y puedes llamarlo así

x <- 0
inc(x)
Thevandalyst
fuente