R: + = (плюс равно) и ++ (плюс плюс) эквивалент из c ++ / c # / java и т. Д.?


Ответы:



64

После @ GregaKešpret вы можете сделать инфиксный оператор:

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

6
(+1), но слово предупреждения. Печатая x = %+=% y/2возвращается x = (x + y)/2. Добавление скобок, т.е. x = %+=% (y/2)решает проблему.
Кнрумси

@knrumsey Почему это? Я бы предположил, что деление будет оператором с более высоким приоритетом.
Дэвид Келли

@DavidKelley Не уверен. Я с тобой там. Я столкнулся с этой проблемой, работая над проектом, и мне потребовался час, чтобы найти проблему.
Кнрумси

Помните, что вы выполняете функцию, а не делаете дополнение. Функции имеют наивысший приоритет, поэтому без скобок они анализируют y как ввод функции, а следующим шагом вниз по цепочке является деление. Скобки поднимают операцию (y / 2) до вершины цепочки.
Джастин

33

R не имеет понятия increment operator(как, например, ++ в C). Тем не менее, это не сложно реализовать самостоятельно, например:

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

В этом случае вы бы позвонили

x <- 10
inc(x)

Тем не менее, он вводит накладные расходы при вызове функции, поэтому он медленнее, чем печатать x <- x + 1самостоятельно. Если я не ошибаюсь, increment operatorбыл введен, чтобы упростить работу для компилятора, так как он может преобразовывать код в эти инструкции машинного языка напрямую.


3
Эта функция не может возвращать значение и затем увеличивать как postincrement ++. Это больше похоже на + = или preincrement ++.
Мегатрон

Неправильно! Увеличение не было введено, чтобы упростить работу компилятора. INCИнструкция была введена в процессорах в основном для реализации счетчиков (см. Руководство разработчика программного обеспечения Intel). Я обновлю ответ.
banan3'14

19

R не имеет этих операций, потому что (большинство) объектов в R являются неизменяемыми. Они не меняются. Обычно, когда кажется, что вы модифицируете объект, вы на самом деле модифицируете копию.


18
В то время как неизменность является отличным / желательным свойством для объектов (читай: меньше ошибок), я не думаю, что неизменность связана с вопросом + =. В других языках + = может применяться к неизменяемым типам (например, строки в .net). Операция просто создает новый объект и присваивает данную переменную этому новому объекту. Неизменность сохраняется, а переменная обновляется.
SFun28

4
Хорошая точка зрения. Однако неизменность делает этот вид операций менее естественным.
Хэдли

15

Увеличение и уменьшение на 10.

require(Hmisc)
inc(x) <- 10 

dec(x) <- 10

7
Эти функции были удалены с Hmiscверсии 4.1.0.
llasram

@llasram, глядя на эту запись, я не могу никого винить.
Берс


3

Мы можем переопределить +. Если +используется унарный, а его аргумент сам является унарным +вызовом, тогда увеличивают соответствующую переменную в вызывающей среде.

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

другие операции не меняются:

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

Не делайте этого, потому что вы все замедляете. Или сделайте это в другой среде и убедитесь, что у вас нет больших циклов в этих инструкциях.

Вы также можете просто сделать это:

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

-1

Есть еще один способ сделать это, который я нахожу очень простым, может быть, может быть от некоторой помощи

Я использую <<-для этих ситуаций операторы <<-присваивают значение родительской среде

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

и вы можете назвать это как

x <- 0
inc(x)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.