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

147

Есть ли в R понятие +=(плюс равно) или ++(плюс плюс) как у c ++ / c # / других?

SFun28
источник
8
Нет, делать x += 1или x++- x = x + 1работает.
Джошуа Доусон

Ответы:

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 являются неизменяемыми. Они не меняются. Обычно, когда кажется, что вы модифицируете объект, вы на самом деле модифицируете копию.

Hadley
источник
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
Moody_Mudskipper
источник
-1

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

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

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

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

x <- 0
inc(x)
Thevandalyst
источник