很抱歉再次提出这样一个常见问题!但是,我在论坛上发现的解决方案都没有解决我的问题......
(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'但是不确定这是否是最好的办法!
非常感谢您的任何建议: - )
一切顺利!
答案 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
个