Question

I would like to interweave two data.frame in R. For example:

a = data.frame(x=1:5, y=5:1)
b = data.frame(x=2:6, y=4:0)

I would like the result to look like:

> x y
  1 5
  2 4
  2 4
  3 3
  3 3
  ...  

obtained by cbinding x[1] with y[1], x[2] with y[2], etc.

What is the cleanest way to do this? Right now my solution involves spitting everthing out to a list and merging. This is pretty ugly:

lst = lapply(1:length(x), function(i) cbind(x[i,], y[i,]))
res = do.call(rbind, lst)
Was it helpful?

Solution 2

You can do this by giving x and y an index, rbind them and sort by the index.

a = data.frame(x=1:5, y=5:1)
b = data.frame(x=2:6, y=4:0)
df <- rbind(data.frame(a, index = 1:nrow(a)), data.frame(b, index = 1:nrow(b)))
df <- df[order(df$index), c("x", "y")]

OTHER TIPS

There is, of course, the interleave function in the "gdata" package:

library(gdata)
interleave(a, b)
#    x y
# 1  1 5
# 6  2 4
# 2  2 4
# 7  3 3
# 3  3 3
# 8  4 2
# 4  4 2
# 9  5 1
# 5  5 1
# 10 6 0

This is how I'd approach:

dat <- do.call(rbind.data.frame, list(a, b))
dat[order(dat$x), ]

do.call was unnecessary in the first step but makes the solution more extendable.

Perhaps this is cheating a bit, but the (non-exported) function interleave from ggplot2 is something I've stolen for my own uses before:

as.data.frame(mapply(FUN=ggplot2:::interleave,a,b))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top