Как работают вложенные операторы замены? - PullRequest
3 голосов
/ 19 октября 2011

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

Вот пример:

a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))

Учитывая эту структуру данных, допустим, я хочу заменить 3-й элемент вложенного числового вектора aaa. Я мог бы сделать что-то вроде:

newvalue <- 100
a$aa$aaa[3] <- newvalue

Делать это кажется достаточно очевидным, но я не мог объяснить себе, как на самом деле это выражение оценивается. Работая с функцией кавычек, я собрал воедино некоторую грубую логику, например:

(1) Создайте и отправьте вызов функции верхнего уровня:

`<-`(a$aa$aaa[3],newvalue)  

(2) Ленивая оценка первого аргумента в (1), вызов функции '[':

`[`(a$aa$aaa,3)    

(3) Приступить рекурсивно вниз:

`$`(a$aa,"aaa")

(4) ... далее, снова позвоните '$':

`$`(a,"aa")

(5) С (4), возвращая фактическую структуру данных, продолжайте обратно «вверх по стеку», заменяя возвращенные структуры данных, пока фактическое назначение не будет выполнено в (1).

Я предполагаю, что моя путаница связана с некоторыми аспектами ленивой оценки и / или сред оценки. В приведенном выше примере я просто переназначил один элемент вектора. Но как получается, что R отслеживает, где этот вектор находится в большей структуре данных?

Приветствия

1 Ответ

1 голос
/ 24 ноября 2011

Я думаю a$aa$aaa[3] работает следующим образом:

Если вы хотите получить доступ к элементу, находящемуся внутри текущего объекта, вы используете одинарные квадратные скобки, []. Это делает элемент доступным, но вы не можете выполнять сложные манипуляции с ним, потому что элемент все еще является частью объекта.

Когда вы получаете доступ к элементу с помощью $, это переводится с a$aa на a[["aa"]], освобождая элемент от текущего объекта.

Общее выражение a$aa$aaa[3] переводится в a[["aa"]][["aaa"]][3]. Это рассматривается как вектор векторов ->

  1. Взять объект a, вектор доступа aa.
  2. Вектор доступа aaa.
  3. Доступ к третьему элементу в векторе aaa.

Оценка R:

 > a
 $aa
 $aa$aaa
 [1]  1  2  3  4  5  6  7  8  9 10

 $aa$bbb
 [1] 11 12 13 14 15 16 17 18 19 20

 $aa$ccc
 [1] 21 22 23 24 25 26 27 28 29 30


 $bb
 $bb$ddd
 [1] 1 2 3 4 5


 > a$aa
 $aaa
 [1]  1  2  3  4  5  6  7  8  9 10

 $bbb
 [1] 11 12 13 14 15 16 17 18 19 20

 $ccc
 [1] 21 22 23 24 25 26 27 28 29 30

 > a$aa$aaa
 [1]  1  2  3  4  5  6  7  8  9 10
 > a[["aa"]]
 $aaa
 [1]  1  2  3  4  5  6  7  8  9 10

 $bbb
 [1] 11 12 13 14 15 16 17 18 19 20

 $ccc
 [1] 21 22 23 24 25 26 27 28 29 30

 > a[["aa"]][["aaa"]]
 [1]  1  2  3  4  5  6  7  8  9 10
 > a["aa"]
 $aa
 $aa$aaa
 [1]  1  2  3  4  5  6  7  8  9 10

 $aa$bbb
 [1] 11 12 13 14 15 16 17 18 19 20

 $aa$ccc
 [1] 21 22 23 24 25 26 27 28 29 30


 > a["aa"]["aaa"]
 $<NA>
 NULL

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...