R: + = (più uguale) e ++ (più più) equivalente da c ++ / c # / java, ecc.?


Risposte:



64

Seguendo @ GregaKešpret puoi creare un operatore infix:

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

6
(+1), ma una parola di avvertimento. La digitazione x = %+=% y/2restituisce x = (x + y)/2. L'aggiunta di parentesi, ovvero x = %+=% (y/2)risolve il problema.
Knrumsey,

@knrumsey Perché è quello? Avrei indovinato che la divisione sarebbe un operatore con precedenza superiore.
David Kelley,

@DavidKelley Non sono sicuro. Sono con te lì. Mi sono imbattuto in questo problema lavorando su un progetto una volta e mi ci è voluta un'ora per trovare il problema.
Knrumsey,

Ricorda che stai eseguendo una funzione, non facendo un'aggiunta. Le funzioni hanno la massima precedenza, quindi senza la parentesi analizza y come input della funzione con la divisione che rappresenta il passo successivo lungo la catena. La parentesi eleva l'operazione (y / 2) in cima alla catena.
Justin il

33

R non ha un concetto di increment operator(come ad esempio ++ in C). Tuttavia, non è difficile implementarlo da soli, ad esempio:

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

In tal caso chiameresti

x <- 10
inc(x)

Tuttavia, introduce un overhead di chiamata di funzione, quindi è più lento della digitazione x <- x + 1. Se non sbaglio è increment operatorstato introdotto per semplificare il lavoro per il compilatore, in quanto potrebbe convertire direttamente il codice in quelle istruzioni del linguaggio macchina.


3
Questa funzione non può restituire il valore e quindi incrementare come un postincremento ++. È più simile a + = o preincrement ++.
Megatron,

Sbagliato! L'incremento non è stato introdotto per facilitare il lavoro del compilatore. INCle istruzioni sono state introdotte nei processori principalmente per l'implementazione dei contatori (vedere il Manuale per gli sviluppatori del software Intel). Aggiornerò la risposta.
banan3'14

19

R non ha queste operazioni perché (la maggior parte) degli oggetti in R sono immutabili. Non cambiano. In genere, quando sembra che tu stia modificando un oggetto, stai effettivamente modificando una copia.


18
Mentre l'immutabilità è una proprietà grande / desiderabile per gli oggetti (leggi: meno bug) Non credo che l'immutabilità si riferisca alla domanda + =. In altre lingue + = può essere applicato a tipi immutabili (come stringhe in .net). L'operazione crea semplicemente un nuovo oggetto e assegna la variabile data a quel nuovo oggetto. L'immutabilità viene mantenuta e la variabile viene aggiornata.
SFun28,

4
Buon punto. L'immutabilità certamente rende questo tipo di operazione meno naturale, tuttavia.
Hadley,

15

Incremento e decremento di 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10

7
Queste funzioni sembrano essere state rimosse dalla Hmiscversione 4.1.0.
llasram,

@llasram guardando quella notazione, non posso incolpare nessuno.
bers


3

Possiamo scavalcare +. Se +viene utilizzato unario e il suo argomento è esso stesso una +chiamata unaria , quindi incrementare la variabile rilevante nell'ambiente chiamante.

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

le altre operazioni non cambiano:

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

Non farlo, perché rallenti tutto. Oppure fallo in un altro ambiente e assicurati di non avere grandi loop su queste istruzioni.

Puoi anche solo fare questo:

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

-1

C'è un altro modo di farlo, che trovo molto semplice, forse potrebbe essere di aiuto

Uso <<-per queste situazioni Gli operatori <<-assegnano il valore all'ambiente padre

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

e puoi chiamarlo come

x <- 0
inc(x)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.