web-dev-qa-db-ja.com

dplyr Rのデカルト積

デカルト積のdplyr関数を見つけようとしています。共通の変数がない2つの単純なdata.frameがあります。

x <- data.frame(x=c("a","b","c"))
y <- data.frame(y=c(1,2,3))

の結果を再現したい

merge(x,y)

  x y
1 a 1
2 b 1
3 c 1
4 a 2
5 b 2
6 c 2
7 a 3
8 b 3
9 c 3

私はすでにこれを探しました(たとえば here または here )何も有用なものを見つけることなく。

どうもありがとうございました

25
Luca Monno

tidyrパッケージの crossing を使用します。

x <- data.frame(x=c("a","b","c"))
y <- data.frame(y=c(1,2,3))

crossing(x, y)

結果:

   x y
 1 a 1
 2 a 2
 3 a 3
 4 b 1
 5 b 2
 6 b 3
 7 c 1
 8 c 2
 9 c 3
33
Gregor Sturm

すべてにお詫び申し上げます。以下の例では、data.framesまたはdata.tablesで動作するように見えますnot

Xとyがデータベースtbls(_tbl_dbi_/_tbl_sql_)の場合、次のことも実行できます。

full_join(x, y, by = character())

2017年末にdplyrに追加され、DBの世界では_CROSS JOIN_にも変換されます。偽の変数を導入しなければならないことの煩わしさを軽減します。

7
dsz

tidyverse出力が必要な場合は、expandからtidyrを使用できます

library(tidyverse)
y %>% 
   expand(y, x= x$x) %>%
   select(x,y)
# A tibble: 9 × 2
#       x     y
#  <fctr> <dbl>
#1      a     1
#2      b     1
#3      c     1
#4      a     2
#5      b     2
#6      c     2
#7      a     3
#8      b     3
#9      c     3
6
akrun

この問題に直面したとき、私は次のようなことをする傾向があります。

x <- data.frame(x=c("a","b","c"))
y <- data.frame(y=c(1,2,3))
x %>% mutate(temp=1) %>% 
inner_join(y %>% mutate(temp=1),by="temp") %>%
dplyr::select(-temp) 

Xとyが複数列のデータフレームであるが、xの行とyの行のすべての組み合わせを実行したい場合、これは、思いつくことができるexpand.grid()オプションよりも優れています。

5
andyyy

これは、dszのコメントの続きです。アイデアは以下から得られました: http://jarrettmeyer.com/2018/07/10/cross-join-dplyr

tbl_1$fake <- 1
tbl_2$fake <- 1
my_cross_join <- full_join(tbl_1, tbl_2, by = "fake") %>%
                 select(-fake)

これを4〜640 obsのサイズの4列のデータでテストしたところ、約1.08秒かかりました。

3
Aaron C
expand.grid(x=c("a","b","c"),y=c(1,2,3))

編集:n次のより複雑なdata.frameの " Y T "からの次のエレガントなソリューションも検討してください。

https://stackoverflow.com/a/21911221/5350791

要するに:

expand.grid.df <- function(...) Reduce(function(...) merge(..., by=NULL), list(...))
expand.grid.df(df1, df2, df3)
3
Damien Cormann