Reputation: 1848
Let I have such a data frame(df):
col1 col2 col3
x1 x3 x4
x2 y1 y2
y3 y4 y5
And let an another input data frame(dfi) is:
col1 col2
y 2
x 1
Desired output data frames are:
data frame1(df1):
col1 col2 col3
x1 y1 y2
x2 y4 y5
data frame2(df2):
col1 col2 col3
y3 y1 x4
y4
data frame3(df3):
col1 col2 col3
y3 x3 y2
y5
Namely,
I want to create data frames where
How can I create such data frames using R? My original data frame is much larger and the second input data frame dfi can change. I know this is difficult problem. I will be very glad for any help. Thanks a lot.
Upvotes: 2
Views: 140
Reputation: 121568
Not exactly what you are looking for( not the same column order). The problem is really very specific so it hard to explain the code but here some notes:
Use col1 of dfi to find 'x' and 'y' columns in df. For x --> xi and for y --> yi. Put the result in a list like this one :
List of 2
$ :List of 3
..$ col1: chr "y3"
..$ col2: chr [1:2] "y1" "y4"
..$ col3: chr [1:2] "y2" "y5"
$ :List of 3
..$ col1: chr [1:2] "x1" "x2"
..$ col2: chr "x3"
..$ col3: chr "x4"
Use col2 of dfi , and list ll to find all combinations using Map
and combin
. We use also the helper function FUN to homogenize vector lengths.
Here the entire code:
ll <- lapply(dfi$col1,function(patt) lapply(df,function(x)x[grep(patt,x)]))
M <- max(dfi$col2)
## helper function to add '' if vectors don't have the same size
FUN = function(x){
res <- lapply(x,function(y){
if(length(y)<M)
y <- c(y,rep('',M-length(y)))
else y
})
as.data.frame(res)
}
ll_dat <- Map(function(x,m)combn(x,m,simplify=F,FUN),ll,dfi$col2)
Map(cbind,ll_dat[[1]],rev(ll_dat[[2]]))
# [1]]
# col1 col2 col3
# 1 y3 y1 x4
# 2 y4
#
# [[2]]
# col1 col3 col2
# 1 y3 y2 x3
# 2 y5
#
# [[3]]
# col2 col3 col1
# 1 y1 y2 x1
# 2 y4 y5 x2
Upvotes: 2