2013-03-18 163 views
-1
f1 <- function(x) { 
    zx1 <- sample(1:nrow(zone4[[x]]), nrow(zone4[[x]]), replace=F) 
    zone4[[x]]$randnums <- zx1 
} 

f1(1) 

## DOESN'T UPDATE zone4[[1]] 

zx2 <- sample(1:nrow(zone4[[1]]), nrow(zone4[[1]]), replace=F) 

zone4[[1]]$randnums <- zx2 

## DOES UPDATE zone[[1]] 

如果我像上面顯示的那樣創建函數f1(),那麼對象'zone4 [[x]]'不會更新。但是,如果我運行與上面相同的命令,但顯式狀態爲'x',如下所示,則更新對象'zone4 [[x]]'。爲什麼會這樣呢?我想知道,因爲我想運行代碼的迭代。如果在上面的函數f1()的定義中,我寫了「names(zone4 [[x]])」,那麼我得到的輸出告訴我該函數做了它應該做的事情,但是當再次查詢時,zone [ x]]似乎沒有改變。感謝您的幫助。這個想法是爲給定年份和另一個變量區域的數據集的每個子集製作隨機數。數據集最初是一個單一的數據框架,但我使用split()函數根據年份和區域(其中有4個)分隔數據。也許有更好的方法將隨機數字分配給特定的數據子集使用split()函數?爲什麼我的功能不能保存我的任務?

+3

你忘記完成你的標題了嗎? – Arun 2013-03-18 23:23:21

回答

5

R功能通常不會有副作用(即在全局對象改變事物)

這是一件好事(大部分的時間,因爲我們不希望意想不到的後果)

的慣用的方法是將結果賦予一個新的對象(它可以是覆蓋原來相同的名稱)

f1 <- function(x) { 
    zx1 <- sample(1:nrow(zone4[[x]]), nrow(zone4[[x]]), replace=F) 
    zone4[[x]]$randnums <- zx1 
    # usually a good idea to return the complete object 
    # especially when a replacement function (in your case `[[<-`) 
    # is the last one called 
    return(zone4) 
} 

zone4 <- f1(1) 

另一種方法是使用data.table

library(data.table) 
zone4 <- lapply(zone4, as.data.table) 

f1 <- function(x) { 
    zone4[[x]][,randnums := sample(.N)] 
    invisible(NULL) 
} 
+0

zone4 < - f1(1) #這樣做只會將隨機數列表放入zone4中。當我嘗試運行多個x值的函數時,我得到了「遞歸索引失敗的級別3」。 – matt 2013-03-21 02:35:48

+0

@ user2184368 - 請舉例說明'zone4'的樣子。你指的是哪個功能? – mnel 2013-03-21 02:47:40

+0

@mnel:如果它是一個更大的數據結構的行/列/切片呢? – smci 2014-03-30 23:29:03