Combine (Rbind) Data Frames and Create Column With Name of Original Data Frames

Combine (rbind) data frames and create column with name of original data frames

It's not exactly what you asked for, but it's pretty close. Put your objects in a named list and use do.call(rbind...)

> do.call(rbind, list(df1 = df1, df2 = df2))
x y
df1.1 1 2
df1.2 3 4
df2.1 5 6
df2.2 7 8

Notice that the row names now reflect the source data.frames.

Update: Use cbind and rbind

Another option is to make a basic function like the following:

AppendMe <- function(dfNames) {
do.call(rbind, lapply(dfNames, function(x) {
cbind(get(x), source = x)
}))
}

This function then takes a character vector of the data.frame names that you want to "stack", as follows:

> AppendMe(c("df1", "df2"))
x y source
1 1 2 df1
2 3 4 df1
3 5 6 df2
4 7 8 df2

Update 2: Use combine from the "gdata" package

> library(gdata)
> combine(df1, df2)
x y source
1 1 2 df1
2 3 4 df1
3 5 6 df2
4 7 8 df2

Update 3: Use rbindlist from "data.table"

Another approach that can be used now is to use rbindlist from "data.table" and its idcol argument. With that, the approach could be:

> rbindlist(mget(ls(pattern = "df\\d+")), idcol = TRUE)
.id x y
1: df1 1 2
2: df1 3 4
3: df2 5 6
4: df2 7 8

Update 4: use map_df from "purrr"

Similar to rbindlist, you can also use map_df from "purrr" with I or c as the function to apply to each list element.

> mget(ls(pattern = "df\\d+")) %>% map_df(I, .id = "src")
Source: local data frame [4 x 3]

src x y
(chr) (int) (int)
1 df1 1 2
2 df1 3 4
3 df2 5 6
4 df2 7 8

Combine two data frames by rows (rbind) when they have different sets of columns

rbind.fill from the package plyr might be what you are looking for.

rbind data frames in R, possible to add more than a number to duplicated rownames?

Instead of storing important information in rownames you can have them in separate column. Use make.unique to have a unique name.

library(dplyr)
library(tibble)

res <- df1 %>%
rownames_to_column() %>%
bind_rows(df2 %>% rownames_to_column()) %>%
mutate(rowname = make.unique(rowname, sep = '_'))

res

# rowname A B
#1 A1 1 1
#2 B1 2 2
#3 C1 3 3
#4 C1_1 1 1
#5 C2 2 2
#6 C3 3 3

If you need the values back as rownames use column_to_rownames.

res %>% column_to_rownames()

# A B
#A1 1 1
#B1 2 2
#C1 3 3
#C1_1 1 1
#C2 2 2
#C3 3 3

rbind dataframes with a different column name

You could use rbindlist which takes different column names. Using @LyzandeR's data

library(data.table) #data.table_1.9.5
rbindlist(list(a,b))
# a b
# 1: 0.8403348 0.1579255
# 2: 0.4759767 0.8182902
# 3: 0.8091875 0.1080651
# 4: 0.9846333 0.7035959
# 5: 0.2153991 0.8744136
# 6: 0.7604137 0.9753853
# 7: 0.7553924 0.1210260
# 8: 0.7315970 0.6196829
# 9: 0.5619395 0.1120331
#10: 0.5711995 0.7252631

Update

Based on the object names of the 12 datasets (i.e. 'Goal1_Costo', 'Goal2_Costo',..., 'Goal12_Costo'),

 nm1 <- paste(paste0('Goal', 1:12), 'Costo', sep="_")
#or using `sprintf`
#nm1 <- sprintf('%s%d_%s', 'Goal', 1:12, 'Costo')
rbindlist(mget(nm1))

Combine two dataframes into one by intercalating the columns of each one of the two original dataframes

Using the built in BOD data frame construct sample df1 and df2 inputs.

Then iterating over the columns convert the jth column of each to a ts series (since ts series can be cbind'ed even with different numbers of rows) and then cbind them and convert that to a data frame. Finally give it nicer names. No packages are used.

# test data
df1 <- BOD # 6x2 data frame w Time and demand col names
df2 <- head(10 * BOD, 3) # 3x2 data frame w same names

nc <- ncol(df1)
out <- do.call("data.frame", lapply(1:nc, function(j) cbind(ts(df1[,j]), ts(df2[,j]))))
names(out) <- make.names(rep(names(df1), each = 2), unique = TRUE)

out

giving:

  Time Time.1 demand demand.1
1 1 10 8.3 83
2 2 20 10.3 103
3 3 30 19.0 190
4 4 NA 16.0 NA
5 5 NA 15.6 NA
6 7 NA 19.8 NA

Combine dataframes with reference to where they came from

Should you simply want a numeric identifier for each data.frame you could do:

library(dplyr)
bind_rows(Right, Left, .id = "Eye")

Which gives:

 Eye Vision Colour Prescription
1 1 0.3 blue -1.0
2 1 -0.1 blue 1.5
3 2 0.0 blue 1.0
4 2 0.1 brown -2.5

You could also put your data.frames in a list and use the names as identifier.

From the documentation:

When .id is supplied, a new column of identifiers is created to link
each row to its original data frame. The labels are taken from the
named arguments to bind_rows(). When a list of data frames is
supplied, the labels are taken from the names of the list
. If no names
are found a numeric sequence is used instead.

Something like:

dat <- c("Right", "Left")
lst <- mget(dat)
bind_rows(lst, .id = "Eye")

Which gives:

    Eye Vision Colour Prescription
1 Right 0.3 blue -1.0
2 Right -0.1 blue 1.5
3 Left 0.0 blue 1.0
4 Left 0.1 brown -2.5


Related Topics



Leave a reply



Submit