0

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.

Community
  • 1
  • 1

2 Answers2

3

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).

lmo
  • 36,904
  • 9
  • 50
  • 61
0

After implementing the code provided by @Imo (thanks!), I was able to convert my list of lists into a dataframe, so the complete code was like this:

# Join all lists in one nested list # 
myLists <- mget(ls(pattern="dist\\d+"))
# Get the max length of those lists #
maxLength <- max(lengths(myLists))
# generating a dataframe from the nested list, making all lengths equal
allDistancesDf <- as.data.frame(do.call(rbind, lapply(myLists, `length<-`, maxLength)))

Thank you all for the help ;)