Sebastian Zeki
Sebastian Zeki

Reputation: 6874

rbind whatever is present in R

I have two dataframes, sometimes.

Sometimes df1 is present, sometimes it isnt. The same goes for df2.

I want to rbind df1 and df2 together but I dont want to write a load of messy nested if conditions to see if they exist. I just want to call rbind and for it to bind together whatever it finds.

I've tried:

  if(!is.null(df2)){
      if(exists("df1") && !is.null(df1)){
        Finalmerge<-rbind(df2,df1)
      }
    }
    else if(is.null(df2)){Finalmerge<-df1}
    else if(!exists(df1)|is.null(df1)){Finalmerge<-df2}

but it makes my head spin and doesn't really work anyway. Is there a way of saying- just rbind whatever is there and dont worry about it if something isnt there?

Upvotes: 0

Views: 311

Answers (3)

Karsten W.
Karsten W.

Reputation: 18440

In addition to the answers already given, I like to suggest using data.table for rbinding and Filter:

candidates <- ls()
candidates <- lapply(candidates, get)
candidates <- Filter(is.data.frame, candidates)
result <- data.table::rbindlist(candidates)

Using data.table::rbindlist is said to be more efficient than do.call(rbind, candidates). You can convert the resulting data.table back to a data.frame.

Upvotes: 0

Pedro Cavalcante
Pedro Cavalcante

Reputation: 444

One way to go about this:

library(purrr)

ls(pattern = "^df") %>%
reduce(~ possibly(rbind, otherwise = NULL)(get(.x)))

Upvotes: 0

user13653858
user13653858

Reputation:

If you create your data frames dynamically, simply store your data frames in a list so that you can run

do.call(rbind, some_list_of_dataframes)

This can really help you if you have multiple data frames generated dynamically and you store them in a list rather than separate data frames.

However, if you want to get all existing objects that are named similarly, you can use e.g. ls():

ls(pattern = "^df")
#> [1] "df1" "df2"

It lists all objects with name starting at "df" that exist in your environment.

To get their vaules, simply use get() (for one object) or mget() (for making a list of all of them).

See this:

# example data
df1 <- mtcars[1:2, ]
df2 <- mtcars[3:4, ]

# get all df...
dataframes <- ls(pattern = "^df")

# rbind them
all <- do.call(rbind, mget(dataframes))

print(all)
#>                     mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> df1.Mazda RX4      21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> df1.Mazda RX4 Wag  21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> df2.Datsun 710     22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> df2.Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1

Created on 2020-07-02 by the reprex package (v0.3.0)

Upvotes: 2

Related Questions