Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind rows without losing those with character(0)?

Tags:

r

rbind

I have a list like L (comes from a vector splitting).

L <- strsplit(c("1 5 9", "", "3 7 11", ""), " ")

# [[1]]
# [1] "1" "5" "9"
# 
# [[2]]
# character(0)
# 
# [[3]]
# [1] "3"  "7"  "11"
# 
# [[4]]
# character(0)

When I do an ordinary rbind as follows, I'm losing all the character(0) rows.

do.call(rbind, L)
#      [,1] [,2] [,3]
# [1,] "1"  "5"  "9" 
# [2,] "3"  "7"  "11"

Do I always have to do a lapply like the following or have I missed something?

do.call(rbind, lapply(L, function(x) 
    if (length(x) == 0)  rep("", 3) else x))
#      [,1] [,2] [,3]
# [1,] "1"  "5"  "9" 
# [2,] ""   ""   ""  
# [3,] "3"  "7"  "11"
# [4,] ""   ""   ""  

Base R answers are preferred.

like image 794
jay.sf Avatar asked Apr 13 '19 06:04

jay.sf


People also ask

How do I bind rows in R?

Row bind using Rbind() & bind_rows() in R. Rbind() function in R row binds the data frames which is a simple joining or concatenation of two or more dataframes (tables) by row wise. In other words, Rbind in R appends or combines vector, matrix or data frame by rows.

How do you Rbind two data frames?

To join two data frames (datasets) vertically, use the rbind function. The two data frames must have the same variables, but they do not have to be in the same order. If data frameA has variables that data frameB does not, then either: Delete the extra variables in data frameA or.

Does Rbind require same number of columns?

So, the column names in both the data frames must be the same if you want to use rbind().

Do call in Rbind?

do. call(rbind, ls) gives you the same output as Reduce(rbind, ls) . The later is less efficient, but it serves to show how you are iterating over the objects in ls rather than manipulating ls (which is a concatenated list of 2 lists) directly.


1 Answers

If you use lapply you don't have to worry about length so you can skip the rep part it will automatically be recycled across columns.

do.call(rbind, lapply(L, function(x) if (length(x) == 0)  "" else x))

#    [,1] [,2] [,3]
#[1,] "1"  "5"  "9" 
#[2,] ""   ""   ""  
#[3,] "3"  "7"  "11"
#[4,] ""   ""   ""  

Another option using same logic as @NelsonGon we can replace the empty lists with blank and then rbind.

L[lengths(L) == 0] <- ""
do.call(rbind, L)

#    [,1] [,2] [,3]
#[1,] "1"  "5"  "9" 
#[2,] ""   ""   ""  
#[3,] "3"  "7"  "11"
#[4,] ""   ""   ""  
like image 101
Ronak Shah Avatar answered Nov 15 '22 07:11

Ronak Shah