22

I'm doing a series of things in dplyr, tidyr, so would like to keep with a piped solution if possible.

I have a list with uneven numbers of elements in each component:

lolz <- list(a = c(2,4,5,2,3), b = c(3,3,2), c=c(1,1,2,4,5,3,3), d=c(1,2,3,1), e=c(5,4,2,2))
lolz
$a
[1] 2 4 5 2 3

$b
[1] 3 3 2

$c
[1] 1 1 2 4 5 3 3

$d
[1] 1 2 3 1

$e
[1] 5 4 2 2

I am wondering if there's a neat one liner to fill up each element with NAs such that they all are of the same length as the element with the maximum items:

I have a 2 liner:

lolz %>% lapply(length) %>% unlist %>% max -> mymax
lolz %>% lapply(function(x) c(x, rep(NA, mymax-length(x))))


$a
[1]  2  4  5  2  3 NA NA

$b
[1]  3  3  2 NA NA NA NA

$c
[1] 1 1 2 4 5 3 3

$d
[1]  1  2  3  1 NA NA NA

$e
[1]  5  4  2  2 NA NA NA

Wondering if I'm missing something quicker / more elegant.

zx8754
  • 52,746
  • 12
  • 114
  • 209
jalapic
  • 13,792
  • 8
  • 57
  • 87

1 Answers1

42

You could use

lapply(lolz, `length<-`, max(lengths(lolz)))
# $a
# [1]  2  4  5  2  3 NA NA
# 
# $b
# [1]  3  3  2 NA NA NA NA
# 
# $c
# [1] 1 1 2 4 5 3 3
# 
# $d
# [1]  1  2  3  1 NA NA NA
# 
# $e
# [1]  5  4  2  2 NA NA NA

or

n <- max(lengths(lolz))
lapply(lolz, `length<-`, n)
lukeA
  • 53,097
  • 5
  • 97
  • 100
  • 1
    never realized you can just overwrite the length of an object. nice! – MichaelChirico Jan 02 '16 at 21:59
  • 2
    I didn't know either - does anyone have any references to what's going on with this functionally? i.e. other uses of `'length<-'` ? – jalapic Jan 02 '16 at 23:42
  • 9
    It's just a short form for `lapply(lolz, function(x) { length(x) <- max(lengths(lolz)); x })`. And `length(x) <- value` _"can be used to reset the length of a vector. If a vector is shortened, extra values are discarded and when a vector is lengthened, it is padded out to its new length with NAs (nul for raw vectors)"_ (see `?length`) – lukeA Jan 03 '16 at 13:03