2017-11-24 5 views
3

標準の "col1" = "col2"結合を使用していないときに、dplyr結合をうまく動かすことができません。ここに私が経験していることの2つの例があります。まずdplyr inner_joinを行う方法col1> col2

:私はこのコードを複製しますが、SQLを使用している場合

library(dplyr) 

tableA <- data.frame(col1= c("a","b","c","d"), 
        col2 = c(1,2,3,4)) 

inner_join(tableA, tableA, by = c("col1"!="col1")) %>% 
    select(col1, col2.x) %>% 
    arrange(col1, col2.x) 

Error: by must be a (named) character vector, list, or NULL for natural joins (not recommended in production code), not logical

私は、次の取得:SQLクエリから

con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:") 

copy_to(con, tableA) 

tbl(con, sql("select a.col1, b.col2 
       from 
       tableA as a 
       inner join 
       tableA as b 
       on a.col1 <> b.col1")) %>% 
    arrange(col1, col2) 

結果:

# Source:  SQL [?? x 2] 
# Database: sqlite 3.19.3 [:memory:] 
# Ordered by: col1, col2 
    col1 col2 
    <chr> <dbl> 
1  a  2 
2  a  3 
3  a  4 
4  b  1 
5  b  3 
6  b  4 
7  c  1 
8  c  2 
9  c  4 
10  d  1 
# ... with more rows 

第二の部分最後に似ています:

inner_join(tableA, tableA, by = c("col1" > "col1")) %>% 
    select(col1, col2.x) %>% 
    arrange(col1, col2.x) 

Error: by must be a (named) character vector, list, or NULL for natural joins (not recommended in production code), not logical

SQLの同等:2番目のSQLクエリから

tbl(con, sql("select a.col1, b.col2 
       from tableA as a 
       inner join tableA as b 
       on a.col1 > b.col1")) %>% 
    arrange(col1, col2) 

結果:

# Source:  SQL [?? x 2] 
# Database: sqlite 3.19.3 [:memory:] 
# Ordered by: col1, col2 
    col1 col2 
    <chr> <dbl> 
1  b  1 
2  c  1 
3  c  2 
4  d  1 
5  d  2 
6  d  3 

誰もがこれらのSQLの例を作成する方法を知っているが、dplyrコードを使用していますか?

答えて

3

library(dplyr) 
library(tidyr) 

expand(tableA, col1, col2) %>% 
    left_join(tableA, by = 'col1') %>% 
    filter(col2.x != col2.y) %>% 
    select(col1, col2 = col2.x) 

結果:2番目のケースでは

# A tibble: 12 x 2 
    col1 col2 
    <fctr> <dbl> 
1  a  2 
2  a  3 
3  a  4 
4  b  1 
5  b  3 
6  b  4 
7  c  1 
8  c  2 
9  c  4 
10  d  1 
11  d  2 
12  d  3 

expand(tableA, col1, col2) %>% 
    left_join(tableA, by = 'col1') %>% 
    filter(col2.x < col2.y) %>% 
    select(col1, col2 = col2.x) 

結果:

# A tibble: 6 x 2 
    col1 col2 
    <fctr> <dbl> 
1  b  1 
2  c  1 
3  c  2 
4  d  1 
5  d  2 
6  d  3 
+0

は、この意志は、データフレームがデータベース上にあり、データベースに接続するためにdplyrを使用している場合にお勧めしますどのようなRのデータフレーム上のために完璧に動作します。私はこれを強調するために主要な問題を編集します。追加の質問をしたときに、より良い、それは新しいものを依頼する –

+1

@DyfanJones – h3rm4n

1

dplyrおよびtidyrを用いた溶液。アイデアは、データフレームを展開して、元のデータフレームに結合を実行することです。その後、前のレコードへNAを埋めるためにtidyrからfillを使用しています。最後に、同じ値とNAを持つレコードを除外する。

library(dplyr) 
library(tidyr) 

tableB <- tableA %>% 
    complete(col1, col2) %>% 
    left_join(tableA %>% mutate(col3 = col2), by = c("col1", "col2")) %>% 
    group_by(col1) %>% 
    fill(col3, .direction = "up") %>% 
    filter(col2 != col3, !is.na(col3)) %>% 
    select(-col3) %>% 
    ungroup() 
tableB 
# # A tibble: 6 x 2 
# col1 col2 
# <chr> <dbl> 
# 1  b  1 
# 2  c  1 
# 3  c  2 
# 4  d  1 
# 5  d  2 
# 6  d  3 

あなたの最初のケースのためのデータ

tableA <- data.frame(col1= c("a","b","c","d"), 
        col2 = c(1,2,3,4), stringsAsFactors = FALSE) 
関連する問題