如何修改 R 函数 lapply 中的 list/vector 参数?
How to modify the list/vector argument in place in the R function lapply?
也许是一个奇怪的问题,但我有一个真实的用例:是否可以就地修改,即当函数运行而不是在副本上时,[=13 中的 list/vector 参数=] R 中的函数?如果是,该怎么做?
由于一些(期望的)副作用,我需要它。
更具体地说,在list/vector参数的每个元素被lapply
'read'(或'used')后,我需要删除它。
此致,
奥利维尔
一些代码来说明我在寻找什么。
Blocked
是一个原子向量,B
是一个列表。
Unblock <- function(M)
{
Blocked[M] <<- FALSE
Length_B_M <- length(B[[M]])
if(Length_B_M > 0)
{
# Vectorised version
UnblockAndUpdateAdjacencyList <- function(Node.Value)
{
Node.Name <- as.character(Node.Value)
Node.Value <<- NULL # This is not correct because it won't delete the argument in place
if(Blocked[Node.Name]) Unblock(Node.Name)
}
lapply(X = B[[M]], FUN = UnblockAndUpdateAdjacencyList)
# Unvectorised version
# 'i' is a vector/list index - integer
# Important: it is necessary to browse items backwards as items from the atomic vector 'B[[M]]' are deleted and thus its length decreases at each iteration
for(i in Length_B_M:1)
{
P <- as.character(B[[M]][i])
B[[M]] <<- B[[M]][-i]
if(Blocked[P]) Unblock(P)
}
}
}
实际上我找到了一个稍微优雅的解决方案,即在 lapply
.
的参数中没有任何显式循环和 vector/list 的任何副本
Unblock <- function(M)
{
Blocked[M] <<- FALSE
Length_B_M <- length(B[[M]])
if(Length_B_M > 0)
{
# Vectorised version
# One solution is to copy the vector/list in the argument of 'lapply' - Actually not even needed
UnblockAndUpdateAdjacencyList <- function(Node.Value)
{
Node.Name <- as.character(Node.Value)
B[[M]] <<- B[[M]][-1]
if(Blocked[Node.Name]) Unblock(Node.Name)
}
#B_M_copy <- B[[M]]
#lapply(X = B_M_copy, FUN = UnblockAndUpdateAdjacencyList)
lapply(X = B[[M]], FUN = UnblockAndUpdateAdjacencyList)
}
}
也许是一个奇怪的问题,但我有一个真实的用例:是否可以就地修改,即当函数运行而不是在副本上时,[=13 中的 list/vector 参数=] R 中的函数?如果是,该怎么做?
由于一些(期望的)副作用,我需要它。
更具体地说,在list/vector参数的每个元素被lapply
'read'(或'used')后,我需要删除它。
此致,
奥利维尔
一些代码来说明我在寻找什么。
Blocked
是一个原子向量,B
是一个列表。
Unblock <- function(M)
{
Blocked[M] <<- FALSE
Length_B_M <- length(B[[M]])
if(Length_B_M > 0)
{
# Vectorised version
UnblockAndUpdateAdjacencyList <- function(Node.Value)
{
Node.Name <- as.character(Node.Value)
Node.Value <<- NULL # This is not correct because it won't delete the argument in place
if(Blocked[Node.Name]) Unblock(Node.Name)
}
lapply(X = B[[M]], FUN = UnblockAndUpdateAdjacencyList)
# Unvectorised version
# 'i' is a vector/list index - integer
# Important: it is necessary to browse items backwards as items from the atomic vector 'B[[M]]' are deleted and thus its length decreases at each iteration
for(i in Length_B_M:1)
{
P <- as.character(B[[M]][i])
B[[M]] <<- B[[M]][-i]
if(Blocked[P]) Unblock(P)
}
}
}
实际上我找到了一个稍微优雅的解决方案,即在 lapply
.
Unblock <- function(M)
{
Blocked[M] <<- FALSE
Length_B_M <- length(B[[M]])
if(Length_B_M > 0)
{
# Vectorised version
# One solution is to copy the vector/list in the argument of 'lapply' - Actually not even needed
UnblockAndUpdateAdjacencyList <- function(Node.Value)
{
Node.Name <- as.character(Node.Value)
B[[M]] <<- B[[M]][-1]
if(Blocked[Node.Name]) Unblock(Node.Name)
}
#B_M_copy <- B[[M]]
#lapply(X = B_M_copy, FUN = UnblockAndUpdateAdjacencyList)
lapply(X = B[[M]], FUN = UnblockAndUpdateAdjacencyList)
}
}