Подтвердить что ты не робот

В R, как я могу проверить, ссылается ли на два имени переменных один и тот же базовый объект?

Например:

A <- 1:10
B <- A

Оба A и B ссылаются на один и тот же базовый вектор.

Прежде чем я начну срывать и внедрять что-то в C... Есть ли функция в R, которая может проверить, ссылаются ли две переменные на один и тот же базовый объект?

Спасибо.

4b9b3361

Ответ 1

Вы можете использовать функцию .Internal inspect:

A <- 1:10
B <- A
.Internal(inspect(A))
# @27c0cc8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
.Internal(inspect(B))  # same
# @27c0cc8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
B[1] <- 21
.Internal(inspect(B))  # different
# @25a7528 14 REALSXP g0c6 [NAM(1)] (len=10, tl=150994944) 21,2,3,4,5,...

Саймон Урбанек написал простой пакет с аналогичной функциональностью. Он назвал... дождитесь его... inspect. Вы можете получить его из R-forge.net, выполнив:

install.packages('inspect',repos='http://www.rforge.net/')

ОБНОВЛЕНИЕ: слово предупреждения:

Я рекомендую вам использовать пакет Simon, потому что я не буду рекомендовать вам позвонить .Internal. Это, конечно, не предназначено для использования в интерактивном режиме, и вполне возможно, что вы можете свернуть свою сессию R, используя ее небрежно.

Ответ 2

Вы можете получить это через tracemem: если они указывают на одну и ту же ячейку памяти, они являются одинаковыми объектами памяти.

> a = 1:10
> b = a
> tracemem(a)
[1] "<0x00000000083885e8"
> tracemem(b)
[1] "<0x00000000083885e8"
> b = 1:10
> tracemem(b)
[1] "<0x00000000082691d0"
> 

Что касается того, почему очень полезно знать, являются ли они одними и теми же объектами: если они указывают на один и тот же объект и там отложенная оценка/ленивая оценка/обещание, тогда, если один объект изменится, расчеты будут приостановлены, а новый блок памяти. В некоторых контекстах задержка может быть существенной. Если есть большие объекты, то ожидание длится, пока выделен и скопирован большой блок памяти. В других случаях это может быть смерть на тысячу разрезов: множество мелких помех и задержек здесь и там.

Обновление (включение комментария Джошуа): Обязательно используйте untracemem(), чтобы вы не получили много результатов. Вы также можете посмотреть retracemem, хотя я еще не могу прокомментировать его утилиту для установки трассировки.