为R中另一个环境中的对象的一部分赋值
Assign values to part of an object in another environment in R
假设我在环境e中定义了两个相似的大对象x,y(数据表)。
我想使用函数 f 以类似的方式更改 x 或 y 的大部分,而无需在 f 的执行环境中创建 x 或 y 的副本。示例:
e <- new.env()
e$x <- c(1,2,3) # imagine this to be BIG (ie. dataframe with 200k vars each 500k rows)
e$y <- c(4,5,6) # same here
e$v <- 2 # minor variables
f <- function(var_str, env, input){
# do some computation on parts of var_str which is either "x" or "y"
# and store these right back into e$x or e$y, respectively.
# ie
str <- paste0(var_str,"[2:3] <- (",var_str,"[2:3])^2 + rep(v,2) + ", deparse(input1),"^3/c(100,101)")
eval(parse(text=str), envir= e)
# this does work but I can image there is an easier/more elegant way
# of doing this.
}
我想在全局环境中定义该函数,并将该函数应用于输入不同变量的 e$x 和 e$y。 IE。执行
f("x", e, c(1,2))
f("y", e, c(3,4))
有没有人对此有一个优雅的解决方案。
eval(parse())
是要避免的。您可以这样参考环境:
e <- new.env()
e$x <- c(1,2,3) # imagine this to be BIG (ie. dataframe with 200k vars each 500k rows)
e$y <- c(4,5,6) # same here
e$v <- 2 # minor variables
f <- function(var_str, env, input){
# do some computation on parts of var_str which is either "x" or "y"
# and store these right back into e$x or e$y, respectively.
# ie
env[[var_str]][2:3] <- (env[[var_str]][2:3])^2 + rep(env$v,2) + input^3/input
}
f("x", e, 1:2)
e$x
#[1] 1 7 15
出于好奇,我尝试使用 the simple example in the R6 tutorial 并想出了这个(作为控制台记录复制)。老实说,我不知道它是否符合请求的非复制要求,但它确实似乎就地修改了一个对象。
# Assumes one has created an R6 constructor named `RC` ...
# slightly extended from the example in section
RC <- setRefClass("RC",
fields = list(x = 'ANY'),
methods = list(
getx = function() x,
setx = function(value) x <<- value,
setsub = function(i,j,val) x[i,j] <<- val
)
)
#--- execution ---
rc <- RC$new()
rc$setx(matrix(1:20, 4,5))
rc
# --- result ---
Reference class object of class "RC"
Field "x":
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
测试 setsub
class 特定函数:
rc$setsub(4,5,0) #Test of setting a single element within an object to a new value
rc
#-------
Reference class object of class "RC"
Field "x":
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 0
rc$setsub(1:4,1:4,0) #Test of setting a range of elements within an object to a new value
rc
# ---------
Reference class object of class "RC"
Field "x":
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 17
[2,] 0 0 0 0 18
[3,] 0 0 0 0 19
[4,] 0 0 0 0 0
因此,通过 setsub
实现 [<-
函数(经过非常简单的测试)确实成功了。使用 self
引用将此扩展到示例的单一努力失败了。
假设我在环境e中定义了两个相似的大对象x,y(数据表)。 我想使用函数 f 以类似的方式更改 x 或 y 的大部分,而无需在 f 的执行环境中创建 x 或 y 的副本。示例:
e <- new.env()
e$x <- c(1,2,3) # imagine this to be BIG (ie. dataframe with 200k vars each 500k rows)
e$y <- c(4,5,6) # same here
e$v <- 2 # minor variables
f <- function(var_str, env, input){
# do some computation on parts of var_str which is either "x" or "y"
# and store these right back into e$x or e$y, respectively.
# ie
str <- paste0(var_str,"[2:3] <- (",var_str,"[2:3])^2 + rep(v,2) + ", deparse(input1),"^3/c(100,101)")
eval(parse(text=str), envir= e)
# this does work but I can image there is an easier/more elegant way
# of doing this.
}
我想在全局环境中定义该函数,并将该函数应用于输入不同变量的 e$x 和 e$y。 IE。执行
f("x", e, c(1,2))
f("y", e, c(3,4))
有没有人对此有一个优雅的解决方案。
eval(parse())
是要避免的。您可以这样参考环境:
e <- new.env()
e$x <- c(1,2,3) # imagine this to be BIG (ie. dataframe with 200k vars each 500k rows)
e$y <- c(4,5,6) # same here
e$v <- 2 # minor variables
f <- function(var_str, env, input){
# do some computation on parts of var_str which is either "x" or "y"
# and store these right back into e$x or e$y, respectively.
# ie
env[[var_str]][2:3] <- (env[[var_str]][2:3])^2 + rep(env$v,2) + input^3/input
}
f("x", e, 1:2)
e$x
#[1] 1 7 15
出于好奇,我尝试使用 the simple example in the R6 tutorial 并想出了这个(作为控制台记录复制)。老实说,我不知道它是否符合请求的非复制要求,但它确实似乎就地修改了一个对象。
# Assumes one has created an R6 constructor named `RC` ...
# slightly extended from the example in section
RC <- setRefClass("RC",
fields = list(x = 'ANY'),
methods = list(
getx = function() x,
setx = function(value) x <<- value,
setsub = function(i,j,val) x[i,j] <<- val
)
)
#--- execution ---
rc <- RC$new()
rc$setx(matrix(1:20, 4,5))
rc
# --- result ---
Reference class object of class "RC"
Field "x":
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
测试 setsub
class 特定函数:
rc$setsub(4,5,0) #Test of setting a single element within an object to a new value
rc
#-------
Reference class object of class "RC"
Field "x":
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 0
rc$setsub(1:4,1:4,0) #Test of setting a range of elements within an object to a new value
rc
# ---------
Reference class object of class "RC"
Field "x":
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 17
[2,] 0 0 0 0 18
[3,] 0 0 0 0 19
[4,] 0 0 0 0 0
因此,通过 setsub
实现 [<-
函数(经过非常简单的测试)确实成功了。使用 self
引用将此扩展到示例的单一努力失败了。