2013-01-14 49 views
6

我擁有一個非嵌套列表(非常簡單)。一些元素是NAs,但可以用同一列表中的其他元素替換。我可以通過全球分配運營商<<-實現此目的。不過,我試圖學習更好的做法(因爲這似乎給我編譯一個包的CRAN notes)。問題:替換列表元素(避免全局分配)

  1. 我可以在沒有全局分配的情況下實現嗎?
  2. 如果不是我怎麼能適當地使用assign(我的方法似乎使一堆相同的數據集的副本,並可能遇到內存問題)。

我試過分配,它不起作用。我也嘗試使用lapply而沒有全局分配,但是我只能得到最後返回的元素,而不是每個元素都被替換的列表。

這裏的問題:

#Fake Data 
L1 <- lapply(1:3, function(i) rnorm(1)) 
L1[4:5] <- NA 
names(L1) <- letters[1:5] 

#items to replace and their replacements (names of elements to replace) 
nulls <- names(L1[sapply(L1, function(x) is.na(x))]) 
replaces <- c("b", "a") 

#doesn't work (returns only last element) 
lapply(seq_along(nulls), function(i) { 
    L1[[nulls[i]]] <- L1[[replaces[i]]] 
    return(L1) 
}) 

#works but considered bad practice by many 
lapply(seq_along(nulls), function(i) { 
    L1[[nulls[i]]] <<- L1[[replaces[i]]] 
}) 

#does not work (I try L1[["d"]] and still get NA) 
lapply(seq_along(nulls), function(i) { 
    assign(paste0("L1[[", nulls[i], "]]"), L1[[replaces[i]]], envir = .GlobalEnv) 
}) 

#also bad practice bu I tried 
lapply(seq_along(nulls), function(i) { 
    assign(paste0("L1$", nulls[i]), L1[[replaces[i]]], envir = .GlobalEnv) 
}) 

#This works but it feels like we're making a ton of copies of the same data set 
lapply(seq_along(nulls), function(i) { 
    L1[[nulls[i]]] <- L1[[replaces[i]]] 
    assign("L1", L1, envir = .GlobalEnv) 
}) 

最後,我想這樣做沒有全局分配,但如果沒有,什麼是對的CRAN構建一個軟件包的最佳實踐。

+1

你爲什麼不使用臨時列出一個向量? – Roland

+1

'lapply' +'<< - '通常意味着你應該使用for循環。 – hadley

+0

@hadley,有用的信息。我敢打賭,這可以擺脫我在我的包構建中得到的一些筆記。 –

回答

10

有一個replace功能會爲你做到這一點:

replace(L1, match(nulls, names(L1)), L1[match(replaces, names(L1))]) 

您也可以使用稍微簡單which(is.na(L1)),而不是match(nulls, names(L1))

4

爲了完整這裏的哈德利的建議for循環一些類似情況下不會允許使用replace

for(i in seq_along(a[!apps])){ 
    L1[[nulls[i]]] <- L1[[replaces[i]]] 
}