4
votes

I have a list containing many data tables. For each of these tables I would like to replaces the NA's with 0.

I know how to change the NA's for each data table separately, but is there a way to put this into one command, e.g., using lapply?

For example: li is a list containing two data table, dt1 and dt2.

li <- list(dt1 = data.table(name = c(4,5), age = c(12, NA)), dt2= data.table(name = c(43,245,243), age = c(354,NA,NA)));

Changing the NA's to 0 in one data.table works like a charm:

d <- "dt1";
li[[d]][is.na(li[[d]])]<-0;

Results in:

> li
$dt1
  name age
1:    4  12
2:    5   0
$dt2
name age
1:   43 354
2:  245  NA
3:  243  NA

But when I try:

test <- lapply(names(li), function(d) li[[d]][is.na(li[[d]])]<-0)

I get:

> test
[[1]]
[1] 0
[[2]]
[1] 0

Is there any way do this without using a loop over all data tables in my list?

3
lapply(li, function(d) {d[is.na(d)] <- 0; d }) - germcd

3 Answers

8
votes

You just need to return the list element

lapply(names(li), function(d) { li[[d]][is.na(li[[d]])] <-0; li[[d]] })
#[[1]]
#   name age
#1:    4  12
#2:    5   0

#[[2]]
#   name age
#1:   43 354
#2:  245   0
#3:  243   0

You could also use:

lapply(li, function(d) { d[is.na(d)] <- 0; d })
5
votes

Another option:

library(dplyr)
lapply(li, function(x) { mutate_each(x, funs(replace(., is.na(.), 0))) })
3
votes

if you want different replacement for NA for different columns. use replace_na function from library tidyr

library(tidyr)
lapply(li,function(df){replace_na(df,list(name=0,age=0))})

Here replace_na wants a list of replacement per column which is useful when you may want to replacement NA in every column with same value.

Hope this works.