2015-12-02 94 views
1

假設我在環境e中定義了兩個類似的大對象x,y(datatable)。 我想用類似的方法改變x或y的很大一部分,而不用在f的執行環境中創建x或y的副本。例如:將值分配給R中另一個環境中的對象的一部分

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)) 

有沒有人有一個優雅的解決方案。

+0

也許你可以得到你想要使用R6類:https://cran.r-project.org/web/packages/R6/vignettes/Introduction.html –

回答

0

出於好奇,我試着用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功能:

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這個(看得很輕測試)實施[<- -function的確實成功。使用self參考一個單一的努力來擴展這個例子確實失敗了。

+0

是的,我也嘗試過「分配」,但是據我所知,該函數並不能讓你在環境e中填充部分對象x和y。 – Robbin

+0

唯一可讓您「就地」重新分配的函數集,即通過引用,即Rcpp或data.table包中的那些函數。 R是一種承諾(類似於按值)的語言。 –

+0

這看起來很有前途!我看看它。謝謝! – Robbin

0

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 
+0

啊這似乎是一個很好的解決方案,但沒有這樣做環境e中的var_str中的變量的副本? – Robbin

+0

Base R子分配當然是一個副本。但是,這是一個無關的問題,因爲無論您分配的環境如何,副本都是必需的。如果這是問題,請使用實現按引用分配的類或函數。例如,存在package data.table(對於類似於數據框架的結構),或者可以編寫一個通過引用分配的Rcpp函數。 – Roland

相關問題