2017-11-24 7 views
3

표준 "col1"= "col2"조인을 사용하지 않을 때 dplyr 조인을 가져 오는 데 어려움이 있습니다. 다음은 내가 경험하고있는 두 가지 예입니다. 첫째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

:

# 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 

두 번째 부분 : 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) 

결과 마지막과 비슷합니다 :

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 상당 : 두 번째 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) 

그 결과, 두 번째 경우를 들어

# 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.에서 dataframes에 완벽하게 작동합니다. 이를 강조하기 위해 주요 쟁점을 편집 할 것입니다. –

+1

@DyfanJones 질문 할 때 새로운 질문을하는 것이 좋습니다. – h3rm4n

1

dplyrtidyr을 사용하는 용액. 아이디어는 데이터 프레임을 확장 한 다음 원본 데이터 프레임에 조인을 수행하는 것입니다. 그 후에 tidyr에서 fill을 사용하여 NA을 이전 레코드에 채우십시오. 마지막으로 동일한 값과 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)