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

时间:2018-03-26 09:30:36

标签: r list dataframe lapply na

很抱歉再次提出这样一个常见问题!但是,我在论坛上发现的解决方案都没有解决我的问题......

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

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

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

另外,我利用这篇文章提出另一个问题:

(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中重复这个。我想在'lapply'中嵌套'apply'但是不确定这是否是最好的办法!

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

一切顺利!

2 个答案:

答案 0 :(得分:2)

正如最近在几个问题中所讨论的那样,不要使用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的好处是方便的包装和受保护的环境。如果您正在尝试更新全局环境中对象的值,那么最好不要尝试逃避该受保护的环境,而只是使用在对象环境中运行的循环&# 39;重新更新存在。

答案 1 :(得分:2)

原因是该函数在赋值后没有返回原始对象。它只返回最后一个赋值为0.因此,在赋值后,返回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在&#39; my_list&#39;

中有list data.frame