x
внутри анонимной функции - , а не x
в глобальной среде (вашей рабочей области).Это копия x
, локальная для анонимной функции.Не так просто сказать, что R копирует объекты в вызовах функций;R будет стремиться не копировать, если это возможно, хотя после того, как вы измените что-либо, R должен скопировать объект.
Как указывает @DWin, эта скопированная версия x
, которая была изменена , , возвращенный вызовом sapply()
, ваш заявленный вывод не тот, который я получаю:
> x <- c(1:10)
> print(x)
[1] 1 2 3 4 5 6 7 8 9 10
> sapply(1:10,function(i){
+ x[i] = 4
+ })
[1] 4 4 4 4 4 4 4 4 4 4
> print(x)
[1] 1 2 3 4 5 6 7 8 9 10
Очевидно, код сделал почти то, что вы думали.Проблема в том, что выходные данные из sapply()
не были назначены объекту и, следовательно, распечатаны, а затем отброшены.
Причина, по которой вы работаете с кодом, связана с правилами области видимости R. Вы действительно должны передатьдля функции в качестве аргументов любые объекты, которые нужны функции.Однако, если R не может найти объект, локальный для функции, он будет искать в родительской среде объект, соответствующий имени, а затем, при необходимости, в родительской среде этой среды, в конечном итоге затрагивая глобальную среду, рабочее пространство.Таким образом, ваш код работает, потому что он в конечном итоге нашел x
для работы, но был немедленно скопирован, эта копия возвращена в конце вызова sapply()
.
Это копирование во многих случаях требует времени и памяти,Это одна из причин, по которой люди думают, что петли for
медленны в R;они не выделяют память для объекта перед заполнением его циклом.Если вы не выделяете память, R должен изменить / скопировать объект, чтобы добавить следующий результат цикла.
Опять же, это не всегда так просто, везде в R, например, в средахгде копия окружения действительно просто ссылается на оригинальную версию:
> a <- new.env()
> a
<environment: 0x1af2ee0>
> b <- 4
> assign("b", b, env = a)
> a$b
[1] 4
> c <- a ## copy the environment to `c`
> assign("b", 7, env = c) ## assign something to `b` in env `c`
> c$b ## as expected
[1] 7
> a$b ## also changed `b` in `a` as `a` and `c` are actually the same thing
[1] 7
Если вы понимаете такие вещи, прочитайте руководство R Определение языка , которое охватывает многие деталио том, что происходит под капотом в R.