Does R have a concept of +=
(plus equals) or ++
(plus plus) as c++/c#/others do?
Following @GregaKešpret you can make an infix operator:
`%+=%` = function(e1,e2) eval.parent(substitute(e1 <- e1 + e2))
x = 1
x %+=% 2 ; x
x = %+=% y/2
returns x = (x + y)/2
. Adding parenthesis, i.e. x = %+=% (y/2)
solves the problem. –
Foot R doesn't have a concept of increment operator
(as for example ++ in C). However, it is not difficult to implement one yourself, for example:
inc <- function(x)
{
eval.parent(substitute(x <- x + 1))
}
In that case you would call
x <- 10
inc(x)
However, it introduces function call overhead, so it's slower than typing x <- x + 1
yourself. If I'm not mistaken increment operator
was introduced to make job for compiler easier, as it could convert the code to those machine language instructions directly.
INC
instruction was introduced in processors primarily for implementing counters (cf. Intel Software Developer's Manual). I will update the answer. –
Proustite R doesn't have these operations because (most) objects in R are immutable. They do not change. Typically, when it looks like you're modifying an object, you're actually modifying a copy.
Increment and decrement by 10.
require(Hmisc)
inc(x) <- 10
dec(x) <- 10
Hmisc
as of version 4.1.0. –
Grisby We released a package, roperators, to help with this kind of thing. You can read more about it here: https://happylittlescripts.blogspot.com/2018/09/make-your-r-code-nicer-with-roperators.html
install.packages('roperators')
require(roperators)
x <- 1:3
x %+=% 1; x
x %-=% 3; x
y <- c('a', 'b', 'c')
y %+=% 'text'; y
y %-=% 'text'; y
# etc
We can override +
. If unary +
is used and its argument is itself an unary +
call, then increment the relevant object in the calling environment.
`+` <- function(e1,e2){
# if binary `+`, keep original behavior
if(!missing(e2)) return(base::`+`(e1, e2))
# if inner call isn't unary `+` called on language object,
# keep original behavior
inner_call <- substitute(e1)
inner_call_is_plus_on_lng <-
length(inner_call) == 2 &&
identical(inner_call[[1]], quote(`+`)) &&
is.language(inner_call[[2]])
if(!inner_call_is_plus_on_lng) return(base::`+`(e1))
eval.parent(substitute(X <- X + 1, list(X = inner_call[[2]])))
}
x <- 10
++x
x
#> [1] 11
other operations don't change :
x + 2
#> [1] 13
x ++ 2
#> [1] 13
+x
#> [1] 11
x
#> [1] 11
I can't really recommend it since you're messing with primitives which are optimised for a reason.
++1
returns 1 –
Darra ++
is incrementing an object in place, it works only on symbols, 1
isn't a symbol, I can't change the value of 1
, so what happens is that I fall back to the default behavior of +
. –
Darra We can also use inplace
library(inplace)
x <- 1
x %+<-% 2
If you want to use i++
in an array to increment the index, you can try i <- i + 1
, for example,
k = 0
a = 1:4
for (i in 1:4)
cat(a[k <- k + 1], " ")
# 1 2 3 4
but here <-
can NOT be replaced with =
, which does not update the index,
k = 0
a = 1:4
for (i in 1:4)
cat(a[k = k + 1], " ")
# 1 1 1 1
since =
and <-
are not always equivalent, as said in ?`<-`
Here is a simpler approach to increment a variable.
inc = 1
for(i in 1:10){
print(paste("Value of inc: ", inc))
inc = sum(c(inc, 1))
}
You will get results as follows
[1] "Value of inc: 1"
[1] "Value of inc: 2"
[1] "Value of inc: 3"
[1] "Value of inc: 4"
[1] "Value of inc: 5"
[1] "Value of inc: 6"
[1] "Value of inc: 7"
[1] "Value of inc: 8"
[1] "Value of inc: 9"
[1] "Value of inc: 10"
© 2022 - 2024 — McMap. All rights reserved.
x += 1
orx++
-x = x + 1
works. – Lollard