嵌套替换运算符如何工作?
我今天正在处理一个列表列表,需要替换其中一个二级列表的元素。做到这一点的方法似乎很明显,但我意识到我实际上并不清楚它为什么有效。
这是一个例子:
a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))
给定这个数据结构,假设我想替换嵌套数值向量 aaa 的第三个元素。我可以这样做:
newvalue <- 100
a$aa$aaa[3] <- newvalue
这样做似乎很明显,但我无法向自己解释这个表达式实际上是如何被求值的。使用 quote 函数,我拼凑了一些粗略的逻辑,大致如下:
(1) 创建并提交顶级函数调用:
`<-`(a$aa$aaa[3],newvalue)
(2) 对 (1) 中的第一个参数进行惰性求值,调用函数“[”:
`[`(a$aa$aaa,3)
(3) 继续向下递归:
`$`(a$aa,"aaa")
(4) ...再往下,再次调用 '$':
`$`(a,"aa")
(5) 当 (4) 返回一个实际的数据结构时,继续“向上堆栈”替换返回的数据结构,直到实际的数据结构被返回。分配是在(1).
我想我的困惑涉及惰性评估和/或评估环境的某些方面。在上面的示例中,我只是重新分配了向量的一个元素。但是 R 如何跟踪该向量在更大的数据结构中的位置呢?
干杯
I was working with a list of lists today and needed to replace an element of one of the second-level lists. The way to do this seemed obvious, but I realized I wasn't actually clear on why it worked.
Here's an example:
a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))
Given this data structure, let's say I want to replace the 3rd element of the nested numeric vector aaa. I could do something like:
newvalue <- 100
a$aa$aaa[3] <- newvalue
Doing this seems obvious enough, but I couldn't explain to myself how this expression actually gets evaluated. Working with the quote function, I cobbled together some rough logic, along the lines of:
(1) Create and submit the top-level function call:
`<-`(a$aa$aaa[3],newvalue)
(2) Lazy evaluation of first argument in (1), call function '[':
`[`(a$aa$aaa,3)
(3) Proceed recursivley down:
`I was working with a list of lists today and needed to replace an element of one of the second-level lists. The way to do this seemed obvious, but I realized I wasn't actually clear on why it worked.
Here's an example:
a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))
Given this data structure, let's say I want to replace the 3rd element of the nested numeric vector aaa. I could do something like:
newvalue <- 100
a$aa$aaa[3] <- newvalue
Doing this seems obvious enough, but I couldn't explain to myself how this expression actually gets evaluated. Working with the quote function, I cobbled together some rough logic, along the lines of:
(1) Create and submit the top-level function call:
`<-`(a$aa$aaa[3],newvalue)
(2) Lazy evaluation of first argument in (1), call function '[':
`[`(a$aa$aaa,3)
(3) Proceed recursivley down:
(a$aa,"aaa")
(4) ...further down, call '$' again:
`I was working with a list of lists today and needed to replace an element of one of the second-level lists. The way to do this seemed obvious, but I realized I wasn't actually clear on why it worked.
Here's an example:
a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))
Given this data structure, let's say I want to replace the 3rd element of the nested numeric vector aaa. I could do something like:
newvalue <- 100
a$aa$aaa[3] <- newvalue
Doing this seems obvious enough, but I couldn't explain to myself how this expression actually gets evaluated. Working with the quote function, I cobbled together some rough logic, along the lines of:
(1) Create and submit the top-level function call:
`<-`(a$aa$aaa[3],newvalue)
(2) Lazy evaluation of first argument in (1), call function '[':
`[`(a$aa$aaa,3)
(3) Proceed recursivley down:
`I was working with a list of lists today and needed to replace an element of one of the second-level lists. The way to do this seemed obvious, but I realized I wasn't actually clear on why it worked.
Here's an example:
a <- list(aa=list(aaa=1:10,bbb=11:20,ccc=21:30),bb=list(ddd=1:5))
Given this data structure, let's say I want to replace the 3rd element of the nested numeric vector aaa. I could do something like:
newvalue <- 100
a$aa$aaa[3] <- newvalue
Doing this seems obvious enough, but I couldn't explain to myself how this expression actually gets evaluated. Working with the quote function, I cobbled together some rough logic, along the lines of:
(1) Create and submit the top-level function call:
`<-`(a$aa$aaa[3],newvalue)
(2) Lazy evaluation of first argument in (1), call function '[':
`[`(a$aa$aaa,3)
(3) Proceed recursivley down:
(a$aa,"aaa")
(4) ...further down, call '$' again:
(a,"aa")
(5) With (4) returning an actual data structure, proceed back "up the stack" substituting the returned data structures until the actual assignment is made in (1).
I guess my confusion involves some aspects of lazy evaluation and/or evaluation environments. In the example above, I've simply reassigned one element of a vector. But how is it that R keeps track of where that vector is within the greater data structure?
Cheers
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为
a$aa$aaa[3]
的工作方式如下:当您想访问仍在当前对象内的元素时,您可以使用单方括号
[]
。这使得该元素可以访问,但您无法使用它执行复杂的操作,因为该元素仍然是对象的一部分。当您使用
$
访问该元素时,它会从a$aa
转换为a[["aa"]]
,从而从当前对象。总表达式
a$aa$aaa[3]
转换为a[["aa"]][["aaa"]][3]
。这被视为向量的向量->a
,访问向量aa
。aaa
。aaa
中的第三个元素。R评估:
希望这有帮助。
I think
a$aa$aaa[3]
works as followed:When you want to access an element still within the current object you use single square brackets,
[]
. This makes the element accesible, but you can not perform complex manipulations with it because the element is still part of the object.When you access the element using
$
, this translates froma$aa
toa[["aa"]]
, thus releasing the element from the current object.The total expression
a$aa$aaa[3]
translates toa[["aa"]][["aaa"]][3]
. This is treated as a vector of vectors ->a
, access vectoraa
.aaa
.aaa
.The R evaluation:
Hope this helps.