在从 alply 获得的数据帧列表中替换每个 0 的 NA 值

Replace NA values per 0's in a list of dataframe obtained from alply

抱歉又问了这么常见的问题!但是,我在论坛上找到的 none 解决方案适用于我的案例...

(1) 我有一个数据帧列表,这些数据帧是通过使用 plyr 库中的 "alply" 函数将 3D 数组拆分成一个列表而获得的。由于我的数据框中有一些 NA 值,我想用 0 替换它们。我尝试了以下方法:

my_list <- lapply(my_list, function(e) e[is.na(e)] <- 0)

这不起作用:我只是将每个数据帧替换为单个“0”值。我在这里错过了什么?在函数中使用重新赋值不好吗? 'my_list' 是 class 'list' 的对象,也是 'split' 的对象。

另外,借这个post再问一个问题:

(2) 当我获得带有 0 而不是 NA 的 df 的最终列表时:我想对 df 列的每个元素应用一个函数。例如,对于我的一个 df:

    $`df1`
          [,1]       [,2]      [,3]
[1,]        0          25        78
[2,]        0           3         0
[3,]       59           0         0
[4,]      739         566       111

我想用频率替换列中的每个元素(例如,对于列 [1],我得到的不是 59,而是 x = 59/(59+739) 的值,而不是739, y = 739/(59+739)。当然,我需要在 df 的每一列和 'my_list' 的每个 df 中重复此操作。我想将 'apply' 嵌套在 'lapply' 但不确定这是否是继续进行的最佳方式!

非常感谢您的任何建议:-)

祝一切顺利!

正如最近在几个问题中讨论的那样,不要使用 lapply 来更新值。使用 for 循环:

不要做:

my_list <- lapply(my_list, function(e) e[is.na(e)] <- 0)

做:

for (e in my_list){
    e[is.na(e)] <- 0
}

这是因为,在 lapply 内部,赋值发生在一个单独的环境中。 lapply 的好处是方便的包装器和受保护的环境。如果您尝试在全局环境中更新对象中的值,最好不要尝试逃离受保护的环境,而只是使用在您正在更新的对象所在的环境中运行的循环。

原因是函数在赋值后没有returning原始对象。它只是 return 最后分配的值 0。因此,在分配之后,return e

my_list <- lapply(my_list, function(e) {
                e[is.na(e)] <- 0
              e
          })

也可以用replace

来完成
my_list <- lapply(my_list, function(e) replace(e, is.na(e), 0))

注意:在这里,我们假设 OP 在 'my_list'

中有 listdata.frame