0

Let's say I have two vectors (in the case below, they're cycles and thedates) that I want to combine every pair combination between them in a list. The code below gives me the output inlist that I want but I don't think it's very efficient. I was trying different things with outer but I couldn't make it work.

library(lubridate)
library(data.table)
cycles <- c(1,2,10*1:24)
thedates <- seq(ymd('2016-08-13',tz='GMT'), ymd('2019-08-13',tz='GMT'),by='day')

inputs <- matrix(nrow=length(thedates)*length(cycles),ncol=2)
inputs[,1]  <- rep(thedates,each=length(cycles))
inputs[,2] <- rep(cycles,length(thedates))
inlist <- lapply(1:nrow(inputs), function(x) c(inputs[x,1], inputs[x,2]))
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Dean MacGregor
  • 11,847
  • 9
  • 34
  • 72
  • What about the `crossing` function from the tidyr package? https://stackoverflow.com/questions/43228379/cartesian-product-with-dplyr-r – Reeza Aug 15 '19 at 19:23
  • 1
    Consider also `expand.grid` from the tinyverse, `base`, package. – Parfait Aug 15 '19 at 19:32
  • FYI - this would be considered a cross or cartesian join, if you're trying to google the join types. – Reeza Aug 15 '19 at 19:35

2 Answers2

2

Since you have data.table as a package, you can use the CJ() cross join function:

CJ(cycles, thedates)

It would be a lot faster than expand.grid:

expand.grid(cycles, thedates)

I also think having a bunch of lists isn't helpful but you could split it as @Reeza provided to match your output.

Cole
  • 11,130
  • 1
  • 9
  • 24
0

This seems to work for me, not sure if it's more efficient though.

z = split(crossing(cycles, thedates), seq(length(cycles) * length(thedates)))

You get a list of lists of each two. If you want a tibble or dataframe, remove the split portion of that code but since you're working with lists I assumed that's something you need.

Reeza
  • 20,510
  • 4
  • 21
  • 38