替换列表元素(避免全局分配)

时间:2013-01-14 15:35:19

标签: r

我有一个非嵌套列表(很简单)。一些元素是NA,但可以用同一列表中的其他元素替换。我可以使用全局赋值运算符<<-来实现这一点。但是我正在尝试学习更好的练习(因为在编译CRAN包时,这似乎给了我notes)。问题:

  1. 我可以在没有全球任务的情况下实现这一目标吗
  2. 如果不能,我怎样才能恰当地使用assign(我的方法似乎是制作了一堆相同数据集的副本,可能会遇到内存问题)。
  3. 我尝试过分配但不起作用。我还试图在没有全局赋值的情况下使用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构建程序包的最佳做法是什么。

2 个答案:

答案 0 :(得分:10)

有一个replace函数会为您执行此操作:

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

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

答案 1 :(得分:4)

为了完整性,这里有hadley关于for循环的建议,因为一些类似的情况不允许使用replace

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