Search code examples
rlistmaxlengthrbind

Get the max length of several lists


I have several lists with similar names, such as "dist124", "dist131" and so on. I am having an issue while binding those lists/arrays in one dataframe. My code is like this:

id <- c(124,131,137,198)
# create the dataframe with nrow as an initial size only for test
# and ncols as the max length of my lists
df <- data.frame(matrix(NA, nrow = 4, ncol = 33))

row.names(df) <- id
a = 1
for(i in id){
    df[a,] <- do.call(rbind, lapply( paste("dist",i, sep=""), get))
    a <- a+1}

Then I get this error message:

Error in [<-.data.frame(*tmp*, a, , value = c(82.4416264694195, 505.003082621159, : replacement has 5 items, need 33

I know that it is because my lists have different lengths, so in order to work around that issue, I thought to change the length of ALL my lists at once (because they are more than 200 lists).

But I couldn't find a solution to get the max length of those lists into the loop.

I've found a solution for lists of unequal lengths here:
adding NA to make all list elements equal length

So I've tried to adapt it to my case, like this:

b <- 1
for(i in id){
    assign()
    n[b] <- length(paste("dist",i, sep=""))
lapply(paste("dist",i, sep=""), `length<-`, n)
b <- b+1}

If I run length(dist124) = length(dist198), for instance, I can make them equal, but I was looking for a loop solution since I have lots of lists to update its lengths.


Solution

  • To get the maximum length of a large number of lists with similar names, you could to the following:

    # put the lists into a list
    myLists <- mget(ls(pattern="dist\\d+"))
    

    Here, the pattern argument is a regular expression that matches any object with the name "dist" followed by numerical digits. mget puts the matched objects into a list. Next,

    # get the maximum length from these lists
    maxLength <- max(lengths(myLists))
    

    The lengths function, introduced in R 3.2.0, calculates the length of each object in a list and is a faster implementation of sapply(myList, length).