R: + = (плюс дорівнює) і ++ (плюс плюс) еквівалент від c ++ / c # / java тощо?


Відповіді:



64

Після @ GregaKešpret ви можете зробити оператора infix:

`%+=%` = 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
Ця функція не може повернути значення, а потім приріст, як постінкремент ++. Він більше схожий на + = або попередній ++.
Мегатрон

Неправильно! Збільшення не було введено, щоб полегшити роботу компілятора. 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

Ми можемо перекрити +. Якщо +використовується unry і її аргумент є самим одинаковим +викликом, то збільшуйте відповідну змінну в середовищі виклику.

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