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
  • 506,650
  • 124
  • 909
  • 1,183
Dean MacGregor
  • 7,861
  • 7
  • 32
  • 61
  • 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
  • 10,670
  • 1
  • 8
  • 22
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
  • 19,001
  • 4
  • 18
  • 36