5

Given a list whose length <= N, what is the best / most efficient way to fill it up with trailing NULLs up to length (so that it has length N).

This is something which is a one-liner in any decent language, but I don't have a clue how to do it (efficiently) in a few lines in R so that it works for every corner case (zero length list etc.).

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
eold
  • 5,972
  • 11
  • 56
  • 75

6 Answers6

9

Let's keep it really simple:

tst<-1:10 #whatever, to get a vector of length 10
tst<-tst[1:15]
Nick Sabbe
  • 11,684
  • 1
  • 43
  • 57
  • That's it. This solution is 2x faster than than the one proposed by Matthew Dowle, and about 5x faster then my clumsy solution. – eold Nov 11 '11 at 18:40
  • 1
    @leden. Yet another way is simply `length(tst)=15`. Any faster? How did you test? – Matt Dowle Nov 11 '11 at 20:14
  • Yep, this is even faster for large lists. Thanks. – eold Nov 11 '11 at 23:32
  • @RomanLuštrik : ahem. Fortunately, it also works for `tst<-list(1,2,3)`. But of course, a list is just a special case of a vector, so I thought I'd provide the more general solution. – Nick Sabbe Nov 17 '11 at 10:27
6

Try this :

> l = list("a",1:3)
> N = 5
> l[N+1]=NULL
> l
[[1]]
[1] "a"

[[2]]
[1] 1 2 3

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL

>
Matt Dowle
  • 58,872
  • 22
  • 166
  • 224
6

How about this ?

> l = list("a",1:3)
> length(l)=5
> l
[[1]]
[1] "a"

[[2]]
[1] 1 2 3

[[3]]
NULL

[[4]]
NULL

[[5]]
NULL
Matt Dowle
  • 58,872
  • 22
  • 166
  • 224
4

Directly editing the list's length appears to be the fastest as far as I can tell:

tmp <- vector("list",5000)
sol1 <- function(x){
    x <- x[1:10000] 
}
sol2 <- function(x){
    x[10001] <- NULL
}
sol3 <- function(x){
    length(x) <- 10000
}

library(rbenchmark)
benchmark(sol1(tmp),sol2(tmp),sol3(tmp),replications = 5000)
       test replications elapsed relative user.self sys.self user.child sys.child
1 sol1(tmp)         5000   2.045 1.394952     1.327    0.727          0         0
2 sol2(tmp)         5000   2.849 1.943383     1.804    1.075          0         0
3 sol3(tmp)         5000   1.466 1.000000     0.937    0.548          0         0

But the differences aren't huge, unless you're doing this a lot on very long lists, I suppose.

joran
  • 169,992
  • 32
  • 429
  • 468
1

I'm sure there are shorter ways, but I would be inclined to do:

l <- as.list(1:10)
N <- 15
l <- c(l, as.list(rep(NA, N - length(l) )))
JD Long
  • 59,675
  • 58
  • 202
  • 294
0

Hi: I'm not sure if you were talking about an actual list but, if you were, below will work. It works because, once you access the element of a vector ( which is a list is ) that is not there, R expands the vector to that length.

length <- 10
temp <- list("a","b")
print(temp)
temp[length] <- NULL
print(temp)
Brian Diggs
  • 57,757
  • 13
  • 166
  • 188
mark leeds
  • 131
  • 3