Попытка передать по ссылке в R - PullRequest
1 голос
/ 21 июня 2020

Я хочу эмулировать вызов по ссылке в R, и в моем поиске наткнулся на эту ссылку https://www.r-bloggers.com/call-by-reference-in-r/.

Используя стратегию, указанную в ссылке выше, я попытался создать функцию который изменит переданный ему целочисленный вектор, а также вернет измененный вектор. Вот его реализация

library(purrr)

fun = function(top){
  stopifnot(is_integer(top))
  top1 <- top
  top1 <- c(top1,4L)
  eval.parent(substitute(top<-top1))
  top1
}

Когда я создаю переменную и передаю эту функцию, она отлично работает, как показано

> k <- c(9L,5L)
> fun(k)
[1] 9 5 4
> k
[1] 9 5 4

Но когда я передаю целочисленный вектор напрямую, он выдает ошибку :

> fun(c(3L,4L))
 Error in c(3L, 4L) <- c(3L, 4L, 4L) : 
  target of assignment expands to non-language object 

Есть ли обходной путь для этой ситуации, когда, если вектор передается напрямую, мы возвращаем только измененный вектор в качестве результата?

Любая помощь будет принята с благодарностью .. .

1 Ответ

0 голосов
/ 21 июня 2020

Для этого нет обходного пути. По сути, вы создали функцию, которая принимает имя переменной в качестве входных данных и изменяет эту переменную как побочный эффект выполнения. Поскольку c(3L,4L) не является именем переменной, функция не может работать должным образом.

Чтобы было ясно, то, что у вас есть прямо сейчас, на самом деле не является передачей по ссылке. Ваша функция внешне похожа на нее, но на самом деле использует некоторые обходные пути, чтобы просто оценить выражение в родительской среде функции, а не в собственном. Этот тип «побочного эффекта» обычно считается плохой практикой (такие изменения трудно отслеживать и отлаживать, и они подвержены ошибкам), и R создан для их предотвращения.

Передача по ссылке в R обычно невозможно , и я не счел это необходимым за более чем десятилетие ежедневного использования R.

...