1

I want to replace all the lists that are empty (numeric(0)) with the value 0 in the following list:

a <- list(numeric(0), 3.13887804749505, c(0.745977548064631, 15.7233179232099, 
4.32068483740438, 19.6680377065919, 9.24007013740377), numeric(0), 
    c(28.8670111833615, 1.27199935252619, 26.6173612819351, 46.8824614685704
    ), c(3.03425142063166, 3.08366863855608, 4.37959434697201, 
    4.00518501422067, 2.05826729526789, 2.29413068424335))

I was trying this:

b <- lapply(a, function(x) ifelse(length(x)==0,0,x))

But I get the first number from every list:

list(0, 3.13887804749505, 0.745977548064631, 0, 28.8670111833615, 
    3.03425142063166)

Is there a way to do this with apply and not with a loop? The loop takes a very long time (the list is very large).

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
asher
  • 174
  • 1
  • 1
  • 12
  • `lapply(a, function(x) if (length(x)==0) 0 else x)` The problem with `ifelse()` is that it returns a vector with the same length as its condition. – jogo Sep 04 '18 at 08:26

2 Answers2

5

We can use lengths to get length of each element of list and then replace zero-length elements with 0.

a[lengths(a) == 0] <- 0

a
#[[1]]
#[1] 0

#[[2]]
#[1] 3.138878

#[[3]]
#[1]  0.7459775 15.7233179  4.3206848 19.6680377  9.2400701

#[[4]]
#[1] 0

#[[5]]
#[1] 28.867011  1.271999 26.617361 46.882461

#[[6]]
#[1] 3.034251 3.083669 4.379594 4.005185 2.058267 2.294131
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
3

While Ronak has shown a superior way for this particular problem it is still useful to see what was the problem with your lapply() attempt - which is using ifelse() incorrectly.

Here is a close alternative that does what intended:

lapply(a, function(x) if (length(x) == 0) 0 else x)

More concisely

lapply(a, \(x) if (length(x)) x else 0)
s_baldur
  • 29,441
  • 4
  • 36
  • 69
  • What now is the problem of the code in the question? ... see my comment to the question! – jogo Sep 04 '18 at 08:48
  • The problem broadly is using ifelse() incorrectly. You have given a more precise answer. – s_baldur Sep 04 '18 at 08:59
  • 1
    @jogo Thanks. Worked perfect. Also these lines work incredibly faster than a simple loop. Is there a short explanation for this? – asher Sep 04 '18 at 09:42
  • @snoram The comment above is for you too. – asher Sep 04 '18 at 09:42
  • @Asher I think it is a rather long explanation: check here: https://stackoverflow.com/questions/7142767/why-are-loops-slow-in-r – s_baldur Sep 04 '18 at 09:45