Reputation: 5646
Suppose I have the following data frame:
foo <- data.frame(a=letters,b=seq(1,26),
n1=rnorm(26),n2=rnorm(26),
u1=runif(26),u2=runif(26))
I want to append columns u1
and u2
to columns n1
and n2
. For now, I found the following way:
df1 <- foo[,c("a","b","n1","n2")]
df2 <- foo[,c("a","b","u1","u2")]
names(df2) <- names(df1)
bar <- rbind(df1,df2)
That does the trick. However, it seems a little bit involved. Am I too picky? Or is there a faster/simpler way to do this in R?
Upvotes: 1
Views: 66
Reputation: 46856
Use Map()
to concatenate the columns, and cbind()
with recycling to arrive at the final data frame.
cbind(foo[1:2], Map(c, foo[3:4], foo[5:6]))
Substitute numerical indexes with column names, if desired.
cbind(foo[c("a", "b")], Map(c, foo[c("n1", "n2")], foo[c("u1", "u2")]))
Upvotes: 2
Reputation: 20463
Short-hand:
rbind(foo[1:4], setNames(foo[c(1, 2, 5, 6)], names(foo[1:4])))
Long-winded:
rbind(foo[c("a", "b", "n1", "n2")], setNames(foo[c("a", "b", "u1", "u2")], c("a", "b", "n1", "n2")))
Long-winded (more DRY):
nms <- c("a", "b", "n1", "n2")
rbind(foo[nms], setNames(foo[c("a", "b", "u1", "u2")], nms))
Upvotes: 1
Reputation: 21621
Here is one way using full_join()
from dplyr
:
library(dplyr)
full_join(df1, df2, by = c("a", "b", "n1" = "u1", "n2" = "u2"))
From the documentation:
full_join
return all rows and all columns from both x and y. Where there are not matching values, returns NA for the one missing.
by
a character vector of variables to join by. If NULL, the default, join will do a natural join, using all variables with common names across the two tables. A message lists the variables so that you can check they're right.
To join by different variables on x and y use a named vector. For example, by = c("a" = "b") will match x.a to y.b.
Upvotes: 3