2
votes

I have the following input.

x <- c("a","b","c")
y <- c(1,2,3)
z <- c("M","N")

df1 = data.frame(x,y)
df2 = data.frame(df1,z)

Output:

Error in data.frame(df1, z) : arguments imply differing number of rows: 3, 2

I want the final dataframe to look like this:

x   y   z
a   1   M 
b   2   M 
c   3   M 
a   1   N 
b   2   N 
c   3   N

Thank you for your help

3

3 Answers

3
votes

This operation is often called a "cross join" or a "cartesian product". You can use the merge function to do a cross join by setting by = NULL.

merge(df1, data.frame(z), by = NULL)
#   x y z
# 1 a 1 M
# 2 b 2 M
# 3 c 3 M
# 4 a 1 N
# 5 b 2 N
# 6 c 3 N

If you're a tidyverse fan, you can also do tidyr::crossing(df1, z).

1
votes

We can use expand.grid

out <- expand.grid(v1 = row.names(df1), z)
cbind(df1[out$v1,], z = out['Var2'])

Or another option is create a list column and unnest

library(dplyr)
library(tidyr)
df1 %>%
     mutate(z = list(z)) %>%
     unnest(c(z))
0
votes

You can use rbind as follows to accomplish the result you want:

df2 = rbind(data.frame(df1,z=z[1]),data.frame(df1,z=z[2]))