Reputation: 313
Sorry for asking again such a common question! However, none of the solutions I have found on the forum worked on my case...
(1) I have a list of dataframes that were obtained by spliting a 3D-array into a list using the "alply" function from the plyr library. Since I have a few NA values within my dataframes, I wanted to replace them by 0's. I tried the following:
my_list <- lapply(my_list, function(e) e[is.na(e)] <- 0)
which does not work: I just get each of my dataframes replaced by a single "0" value. What am I missing here? Is it bad to use reassignation within a function? 'my_list' is an object of class 'list' but also 'split'.
Also, I take advantage of this post to ask another question:
(2) When i obtain my final list of df's with 0's instead of NA's: I would like to apply a function on each element of a df's column. For instance, for one of my df's:
$`df1`
[,1] [,2] [,3]
[1,] 0 25 78
[2,] 0 3 0
[3,] 59 0 0
[4,] 739 566 111
I would like to replace each element of a column by its frequency (e.g., for column [,1] I'd get, instead of 59, the value x = 59/(59+739) and instead of 739, y = 739/(59+739). Or course, I need this to be repeated across each column of a df and each df of 'my_list'. I wanted to nest 'apply' within a 'lapply' but not sure if this is the best way to proceed!
Thank you very much for any suggestion :-)
All the best!
Upvotes: 1
Views: 751
Reputation: 887501
The reason is that the function is not returning the original object after the assignment. It is only returning the last assigned value which is 0. So, after the assignment, return e
my_list <- lapply(my_list, function(e) {
e[is.na(e)] <- 0
e
})
It can be also be done with replace
my_list <- lapply(my_list, function(e) replace(e, is.na(e), 0))
NOTE: Here, we assume that the OP have a list
of data.frame
s in the 'my_list'
Upvotes: 3
Reputation: 7630
As has been discussed in a few questions recently, don't use lapply
to update values. Use a for loop:
Dont do:
my_list <- lapply(my_list, function(e) e[is.na(e)] <- 0)
Do:
for (e in my_list){
e[is.na(e)] <- 0
}
This is because, inside lapply
, the assignment occurs in a separate environment. The benefit of lapply
is a convenient wrapper and a protected environment. If you're trying to update a value in an object in your global environment, it's best not to try to escape that protected environment, but instead just use a loop that runs in the environment where the object you're updating exists.
Upvotes: 2