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.frame
s.
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 tobind_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
Multiplying All Columns in Dataframe by Single Column
Duplicating Rows in R Merge Function
Split an Audio File into Pieces of an Arbitrary Size
Combing a Categorical Variable to Create a New Categorical Variable in R
Conditional Replacement of a Comma With a Dot in a Numeric Column
Error in Confusion Matrix:The Data and Reference Factors Must Have the Same Number of Levels
How to Change the Spacing Between Legend Items in Ggplot2
Add Legend to Geom_Line() Graph in R
How to Filter Multiple Columns With Same Condition in R
Splitting a Large Data Frame into Smaller Segments
Rstudio Does Not Display Any Output in Console After Entering Code
Change R Default Library Path Using .Libpaths in Rprofile.Site Fails to Work
Using Ggplot2, How to Insert a Break in the Axis
Ggplot2 Stacked Bar Chart - Each Bar Being 100% and With Percenage Labels Inside Each Bar
Adding Value from One Data.Frame to Another Data.Frame by Matching a Variable