我今天正在使用列表列表,需要替换其中一个二级列表的元素。这样做的方式似乎很明显,但我意识到我实际上并不清楚它为什么会起作用。
以下是一个例子:
a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))
给定这个数据结构,假设我想替换嵌套数值向量aaa的第3个元素。我可以做类似的事情:
newvalue <- 100
a$aa$aaa[3] <- newvalue
这样做似乎很明显,但我无法向自己解释这个表达式是如何实际评估的。使用引用函数,我按照以下方式拼凑了一些粗略的逻辑:
(1)创建并提交顶级函数调用:
`<-`(a$aa$aaa[3],newvalue)
(2)懒惰评估(1)中的第一个参数,调用函数'[':
`[`(a$aa$aaa,3)
(3)继续进行recursivley:
`$`(a$aa,"aaa")
(4)......再向下,再次打电话给'$':
`$`(a,"aa")
(5)在(4)返回实际数据结构的情况下,返回“向上堆栈”替换返回的数据结构,直到在(1)中进行实际赋值。
我想我的困惑涉及懒惰评估和/或评估环境的某些方面。在上面的例子中,我只是重新分配了一个向量的一个元素。但是,如何跟踪R在更大的数据结构中的位置呢?
干杯
答案 0 :(得分:1)
我认为a$aa$aaa[3]
的工作原理如下:
如果要访问仍在当前对象中的元素,请使用单个方括号[]
。这使得元素可以访问,但是你不能用它执行复杂的操作,因为元素仍然是对象的一部分。
使用$
访问元素时,会从a$aa
转换为a[["aa"]]
,从而从当前对象释放元素。
总表达式a$aa$aaa[3]
转换为a[["aa"]][["aaa"]][3]
。这被视为矢量矢量 - &gt;
a
,访问向量aa
。aaa
。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
希望这有帮助。