R: + = (mais iguais) e ++ (mais mais) equivalente de c ++ / c # / java, etc.?


Respostas:



64

Seguindo @ GregaKešpret, você pode criar um operador de infix:

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

6
(+1), mas uma palavra de aviso. Digitando x = %+=% y/2retorna x = (x + y)/2. Adicionar parênteses, ou seja, x = %+=% (y/2)resolve o problema.
knrumsey

@knrumsey Por que isso? Eu imaginaria que a divisão seria um operador de precedência mais alta.
David Kelley

@DavidKelley Não tenho certeza. Eu estou com você lá. Encontrei este problema trabalhando em um projeto uma vez e levei uma hora para encontrar o problema.
knrumsey

Lembre-se de que você está executando uma função, não fazendo uma adição. As funções têm a precedência mais alta; portanto, sem parênteses, ele analisa y como entrada da função, com a divisão sendo o próximo passo na cadeia. Os parênteses elevam a operação (y / 2) para o topo da cadeia.
Justin

33

R não tem um conceito de increment operator(como por exemplo ++ em C). No entanto, não é difícil implementar você mesmo, por exemplo:

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

Nesse caso, você chamaria

x <- 10
inc(x)

No entanto, ele introduz despesas gerais de chamada de função, por isso é mais lento do que digitar x <- x + 1você mesmo. Se não me engano, increment operatorfoi introduzido para facilitar o trabalho do compilador, pois ele poderia converter o código diretamente nessas instruções de linguagem de máquina.


3
Esta função não pode retornar o valor e incrementar como um pós-incremento ++. É mais parecido com + = ou pré-incremento ++.
Megatron

Errado! A incremento não foi introduzida para facilitar o trabalho do compilador. INCAs instruções foram introduzidas nos processadores principalmente para a implementação de contadores (consulte o Intel Software Developer's Manual). Eu atualizarei a resposta.
precisa saber é o seguinte

19

R não possui essas operações porque (a maioria) dos objetos em R são imutáveis. Eles não mudam. Normalmente, quando parece que você está modificando um objeto, na verdade está modificando uma cópia.


18
Embora a imutabilidade seja uma propriedade ótima / desejável para objetos (leia-se: menos bugs), não acho que a imutabilidade esteja relacionada à questão + =. Em outros idiomas, + = pode ser aplicado a tipos imutáveis ​​(como strings em .net). A operação simplesmente cria um novo objeto e atribui a variável fornecida a esse novo objeto. A imutabilidade é mantida e a variável é atualizada.
SFun28

4
Bom ponto. A imutabilidade certamente torna esse tipo de operação menos natural, no entanto.
Hadley

15

Incrementar e diminuir em 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10

7
Essas funções parecem ter sido removidas Hmiscda versão 4.1.0.
Llasram

@llasram olhando para essa notação, não posso culpar ninguém.
bers


3

Nós podemos substituir +. Se unário +for usado e seu argumento for uma +chamada unária , aumente a variável relevante no ambiente de chamada.

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

outras operações não mudam:

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

Não faça isso, pois você diminuirá tudo. Ou faça-o em outro ambiente e verifique se você não possui grandes loops nessas instruções.

Você também pode fazer isso:

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

-1

Existe outra maneira de fazer isso, que eu acho muito fácil, talvez possa ser de alguma ajuda

Eu uso <<-para essa situação Os operadores <<-atribuem o valor ao ambiente pai

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

e você pode chamar assim

x <- 0
inc(x)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.