R: + = (plus równa się) i ++ (plus plus) odpowiednik z c ++ / c # / java itp.?

147

Czy R ma koncepcję +=(plus równa się) lub ++(plus plus) tak jak c ++ / c # / others?

SFun28
źródło
8
Nie, do zrobienia x += 1lub x++- x = x + 1działa.
Joshua Dawson

Odpowiedzi:

64

Podążając za @ GregaKešpret, możesz utworzyć operator wrostek:

`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x
baptiste
źródło
6
(+1), ale słowo ostrzeżenia. Wpisywanie x = %+=% y/2zwraca x = (x + y)/2. Dodanie nawiasów, czyli x = %+=% (y/2)rozwiązanie problemu.
knrumsey
@knrumsey Dlaczego tak jest? Domyśliłbym się, że dzielenie będzie operatorem wyższego priorytetu.
David Kelley,
@DavidKelley Nie jestem pewien. Jestem tam z tobą. Raz napotkałem ten problem podczas pracy nad projektem i znalezienie go zajęło mi godzinę.
knrumsey
Pamiętaj, że uruchamiasz funkcję, a nie dodajesz. Funkcje mają najwyższy priorytet, więc bez nawiasów analizuje y jako dane wejściowe funkcji, przy czym dzielenie jest następnym krokiem w dół łańcucha. Nawiasy podnoszą operację (y / 2) na początek łańcucha.
Justin
33

R nie ma pojęcia increment operator(jak na przykład ++ w C). Jednak nie jest to trudne do wykonania samodzielnie, na przykład:

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

W takim razie zadzwonisz

x <- 10
inc(x)

Jednak wprowadza narzut wywołania funkcji, więc jest wolniejszy niż x <- x + 1sam wpisywanie . Jeśli się nie mylę, increment operatorzostał wprowadzony, aby ułatwić pracę kompilatorowi, ponieważ może on bezpośrednio konwertować kod na instrukcje języka maszynowego.

Grega Kešpret
źródło
3
Ta funkcja nie może zwracać wartości, a następnie zwiększać jak postincrement ++. Jest bardziej podobny do + = lub preincrement ++.
Megatron,
Źle! Przyrost nie został wprowadzony, aby ułatwić pracę kompilatora. INCInstrukcja została wprowadzona w procesorach głównie do implementacji liczników (por. Podręcznik programisty Intel). Zaktualizuję odpowiedź.
banan3'14
19

R nie ma tych operacji, ponieważ (większość) obiektów w R jest niezmienna. One się nie zmieniają. Zwykle, gdy wygląda na to, że modyfikujesz obiekt, w rzeczywistości modyfikujesz kopię.

hadley
źródło
18
Podczas gdy niezmienność jest świetną / pożądaną właściwością obiektów (czytaj: mniej błędów), nie sądzę, aby niezmienność odnosiła się do pytania + =. W innych językach + = można zastosować do typów niezmiennych (takich jak ciągi znaków w .net). Operacja po prostu tworzy nowy obiekt i przypisuje daną zmienną do tego nowego obiektu. Niezmienność jest utrzymywana, a zmienna jest aktualizowana.
SFun28
4
Słuszna uwaga. Niezmienność z pewnością sprawia, że ​​ten rodzaj operacji jest jednak mniej naturalny.
hadley
15

Zwiększ i zmniejsz o 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10
Wędrowiec
źródło
7
Wygląda na to, że te funkcje zostały usunięte Hmiscw wersji 4.1.0.
llasram,
@llasram patrząc na ten zapis, nie mogę nikogo winić.
bers
3

Możemy zastąpić +. Jeśli +używane jest jednoargumentowe, a jego argument sam w sobie jest jednoargumentowym +wywołaniem, zwiększ odpowiednią zmienną w środowisku wywołującym.

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

inne operacje nie zmieniają się:

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

Nie rób tego jednak, bo wszystko spowolni. Lub zrób to w innym środowisku i upewnij się, że nie masz dużych pętli w tych instrukcjach.

Możesz też po prostu to zrobić:

`++` <- function(x) eval.parent(substitute(x <-x +1))
a <- 1
`++`(a)
a
# [1] 2
Moody_Mudskipper
źródło
-1

Jest inny sposób na zrobienie tego, który uważam za bardzo łatwy i może nie być pomocny

Używam <<-w tej sytuacji Operatorzy <<-przypisują wartość do środowiska nadrzędnego

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

i możesz to nazwać jak

x <- 0
inc(x)
Thevandalyst
źródło