日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

left join 不重复_R语言ETL工程:连接(join)

發(fā)布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 left join 不重复_R语言ETL工程:连接(join) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作者:黃天元,復旦大學博士在讀,目前研究涉及文本挖掘、社交網(wǎng)絡(luò)分析和機器學習等。希望與大家分享學習經(jīng)驗,推廣并加深R語言在業(yè)界的應(yīng)用。

郵箱:huang.tian-yuan@qq.com

本章將會介紹如何在R中完成數(shù)據(jù)表的連接操作。首先要明確一個問題:為什么要進行連接?本質(zhì)上來說,連接就是按照一定的對應(yīng)規(guī)則,把兩個表格合并為一個表格的操作。舉個例子:比如我們一張表格中有樂隊的歌手名字和他們所屬的樂隊,另一張表格有歌手的名字和他們擅長的樂器類型。因為兩張表格都含有歌手的名字,而歌手的名字也是唯一的(在數(shù)據(jù)庫理論框架中,這個屬性被稱為主鍵),即不存在一張表格會重復出現(xiàn)同一個歌手的名字。這個時候,我們就希望把兩張表格合并起來,做一張包含歌手名字、所屬樂隊、擅長樂器的大表格。通過連接,我們能夠把眾多表格的數(shù)據(jù)合并起來,從而讓孤立的數(shù)據(jù)能夠聯(lián)系在一起。

本章會采用較為簡單的數(shù)據(jù)集進行實現(xiàn),下面我們會參考dplyr的幫助文檔舉例,前期準備如下:

1library(tidyverse) 2band_members 3 4##?#?A?tibble:?3?x?2 5##?name?band? 6##??? 7##?1?Mick?Stones? 8##?2?John?Beatles 9##?3?Paul?Beatles1011band_instruments1213##?#?A?tibble:?3?x?214##?name?plays?15##???16##?1?John?guitar17##?2?Paul?bass?18##?3?Keith?guitar1920band_instruments22122##?#?A?tibble:?3?x?223##?artist?plays?24##???25##?1?John?guitar26##?2?Paul?bass?27##?3?Keith?guitar

觀察表格,我們可以知道,band_members包含了歌手名稱和樂隊信息,band_instruments包含歌手名稱和樂器信息,band_instruments2與band_instrument包含的信息一樣,但是歌手名稱的列名稱由name變化為artist。

基本概念

連接分為很多種,包括內(nèi)連接、全鏈接、左連接、右連接等。我們先介紹一些基礎(chǔ)的邏輯,先看下面這張圖:

下面我們逐個講解這些連接的概念。 首先我們來講內(nèi)連接,又叫做自然連接。還是歌手、樂隊、樂器的例子,比如我們的A表格中有歌手名稱和樂隊的信息,B表格中有歌手名稱和擅長樂器的信息。另外,我們發(fā)現(xiàn)兩張表格中,A表格包含的歌手信息和B表格不同,有的歌手只有A表格有,B表格就沒有;有的歌手只有B表格有,但是A表格沒有。但是我們還是希望把A表格和B表格連接起來,形成一個大表格C。采用內(nèi)連接的話,就會把A表格和B表格都有的歌手提取出來(也就是取了一個交集),然后對兩個表格的列進行連接。


下面介紹左連接和右連接。如果是A表格左連接B表格的話,那么就是A表格的歌手肯定全部保留,如果在A里面有的歌手,在B中找不到,那么就需要填充缺失值,一切以A表格為主。理解了左連接,右連接就非常簡單了,它其實就是左連接的逆運算,也就是說A右連接B,實際就是B左連接A。就是這么簡單。 最后我們講一下全連接。全連接就是A表格B表格的歌手我們統(tǒng)統(tǒng)都保留,但是如果A表格有的歌手B表格沒有,那么在B表格的列中就需要填充缺失值;同理,如果B表格的歌手A沒有,那么A表格帶來的列也需要填充缺失值。


如果還是不理解,可以看一下下面這一張圖片。

基本連接實操

內(nèi)

連接

1band_members?%>% 2inner_join(band_instruments) 3 4##?Joining,?by?=?"name" 5 6##?#?A?tibble:?2?x?3 7##?name?band?plays? 8##???? 9##?1?John?Beatles?guitar10##?2?Paul?Beatles?bass

SQL代碼如下:

1?SELECT?`TBL_LEFT`.`name`?AS?`name`,?`TBL_LEFT`.`band`?AS?`band`,?`TBL_RIGHT`.`plays`?AS?`plays`2FROM?`band_members`?AS?`TBL_LEFT`3INNER?JOIN?`band_instruments`?AS?`TBL_RIGHT`4ON?(`TBL_LEFT`.`name`?=?`TBL_RIGHT`.`name`)

需要注意的是,如果沒有指定根據(jù)哪個列(主鍵)進行合并,那么在連接的時候,函數(shù)會自動默認用兩個表格都包含的列進行連接。在我們的例子中,因為兩個表格都包含名為name的列,因此會根據(jù)name來進行連接。如果需要指定用哪些列進行連接,可以更改by參數(shù),例子如下:

1band_members?%>%?2inner_join(band_instruments2,?by?=?c("name"?=?"artist"))34##?#?A?tibble:?2?x?35##?name?band?plays?6##????7##?1?John?Beatles?guitar8##?2?Paul?Beatles?bass

這樣一來,我們就用band_members的name列與band_instrument2的artist進行了連接。

另外一點需要明確的是,合并之后,兩個表合并的鍵只會保留其中一個,也就是第一個表。如果兩者的鍵的名稱不一樣,也只會保留第一個,比如上面的例子中,我們合并的表格已經(jīng)沒有出現(xiàn)artist這一列,而是統(tǒng)一合并到name這一列中。

連接

1band_members?%>%? 2left_join(band_instruments) 3 4##?Joining,?by?=?"name" 5 6##?#?A?tibble:?3?x?3 7##?name?band?plays? 8##???? 9##?1?Mick?Stones??10##?2?John?Beatles?guitar11##?3?Paul?Beatles?bass

SQL代碼如下:

1?SELECT?`TBL_LEFT`.`name`?AS?`name`,?`TBL_LEFT`.`band`?AS?`band`,?`TBL_RIGHT`.`plays`?AS?`plays`2FROM?`band_members`?AS?`TBL_LEFT`3LEFT?JOIN?`band_instruments`?AS?`TBL_RIGHT`4ON?(`TBL_LEFT`.`name`?=?`TBL_RIGHT`.`name`)

連接

1band_members?%>%? 2right_join(band_instruments) 3 4##?Joining,?by?=?"name" 5 6##?#?A?tibble:?3?x?3 7##?name?band?plays? 8##???? 9##?1?John?Beatles?guitar10##?2?Paul?Beatles?bass?11##?3?Keith??guitar

SQL代碼如下:

1?SELECT?`TBL_RIGHT`.`name`?AS?`name`,?`TBL_LEFT`.`band`?AS?`band`,?`TBL_RIGHT`.`plays`?AS?`plays`2FROM?`band_members`?AS?`TBL_LEFT`3RIGHT?JOIN?`band_instruments`?AS?`TBL_RIGHT`4ON?(`TBL_LEFT`.`name`?=?`TBL_RIGHT`.`name`)

連接

1band_members?%>%? 2full_join(band_instruments) 3 4##?Joining,?by?=?"name" 5 6##?#?A?tibble:?4?x?3 7##?name?band?plays? 8##???? 9##?1?Mick?Stones??10##?2?John?Beatles?guitar11##?3?Paul?Beatles?bass?12##?4?Keith??guitar

SQL代碼如下:

1?SELECT?coalesce(`TBL_LEFT`.`name`,?`TBL_RIGHT`.`name`)?AS?`name`,?`TBL_LEFT`.`band`?AS?`band`,?`TBL_RIGHT`.`plays`?AS?`plays`2FROM?`band_members`?AS?`TBL_LEFT`3FULL?JOIN?`band_instruments`?AS?`TBL_RIGHT`4ON?(`TBL_LEFT`.`name`?=?`TBL_RIGHT`.`name`)

大家可以通過觀察結(jié)果來體會不同連接的效果。

如果兩個表格中用相同名字的列怎么辦?連接函數(shù)會自動給同名列加入后綴,比如A表格和B表格都有一列名為same,那么合并之后,會出現(xiàn)兩列,名字分別為same.x和same.y。后綴名是可以變更的,你可以通過suffix參數(shù)對后綴名進行設(shè)置。

于多個列進行連接

有時候我們不僅僅需要基于單列連接,而且要用到基于多個列的連接。比如我們遇到這么一個問題:我們兩個表格都有年、月、日的數(shù)據(jù),我們需要把兩個表格按照日期對應(yīng)起來,那么就需要年月日都對的上號才能夠進行連接。下面我們來舉個例子,我們先構(gòu)造兩個表:

1d1? 2x?=?letters[4:6], 3y?=?LETTERS[4:6], 4a?=?rnorm(3) 5) 6 7d2? 8x2?=?letters[6:4], 9y2?=?LETTERS[6:4],10b?=?rnorm(3)11)1213d11415##?#?A?tibble:?3?x?316##?x?y?a17##???18##?1?d?D?0.140?19##?2?e?E?0.074620##?3?f?F?-0.5492122d22324##?#?A?tibble:?3?x?325##?x2?y2?b26##???27##?1?f?F?-0.35528##?2?e?E?-1.47?29##?3?d?D?-0.490

下面我們要把d1和d2連接起來,根據(jù)它們的前兩列:

1left_join(d1,?d2,?by?=?c("x"?=?"x2",?"y"?=?"y2"))23##?#?A?tibble:?3?x?44##?x?y?a?b5##????6##?1?d?D?0.140?-0.4907##?2?e?E?0.0746?-1.47?8##?3?f?F?-0.549?-0.355

如果不能夠確定兩個表格中是否有以及有多少相同的列名稱,在連接的時候應(yīng)該總是指定by參數(shù),來決定兩個表格究竟基于什么鍵進行連接。

事實上,兩個表格的連接可以基于無窮多的列,比如年月日就涉及了3列,如果再加上地理位置等信息,就更多了。這也充分告訴我們,連接能夠給我們連接數(shù)據(jù)帶來巨大的便利。

連接(semi_join)與反連接(anti_join)

半連接與反連接在實際工作中相對比較少用,但是這也取決于你的工作內(nèi)容是什么。首先需要聲明的是,半連接和反連接都只會返回“左表”的內(nèi)容,也就是A表格與B表格進行半連接或反連接的時候,只會返回A表格的信息,不會返回B表格的信息。其中,半連接其實相當于進行了一次內(nèi)連接,不過,它不會保留B表格的任何內(nèi)容(也就是沒有保留B表格的列)。反連接則與半連接相反,它會匹配在A表格出現(xiàn)而B表格沒有出現(xiàn)的鍵值,比如A表格x列出現(xiàn)了a,b,c,B表格x列出現(xiàn)了b,c,d,那么半連接會保留A表格x列出現(xiàn)b,c的記錄,反連接則會保留A表格x列出現(xiàn)a的記錄。

紙上得來終覺淺,我們來進行實際操作:

1band_members?%>%? 2semi_join(band_instruments) 3 4##?Joining,?by?=?"name" 5 6##?#?A?tibble:?2?x?2 7##?name?band? 8##??? 9##?1?John?Beatles10##?2?Paul?Beatles1112band_members?%>%?13anti_join(band_instruments)1415##?Joining,?by?=?"name"1617##?#?A?tibble:?1?x?218##?name?band?19##???20##?1?Mick?Stones

SQL代碼如下:

1?SELECT?*?FROM?`band_members`?AS?`TBL_LEFT` 2 3WHERE?EXISTS?( 4SELECT?1?FROM?`band_instruments`?AS?`TBL_RIGHT` 5WHERE?(`TBL_LEFT`.`name`?=?`TBL_RIGHT`.`name`) 6) 7 8?SELECT?*?FROM?`band_members`?AS?`TBL_LEFT` 910WHERE?NOT?EXISTS?(11SELECT?1?FROM?`band_instruments`?AS?`TBL_RIGHT`12WHERE?(`TBL_LEFT`.`name`?=?`TBL_RIGHT`.`name`)13)

結(jié)

本章介紹了強大的數(shù)據(jù)表連接操作,在實際工作中,連接操作的速度是非常快的,效率極高。對于內(nèi)連接、全連接、左連接、右連接是我們工作中最常用的連接方法,需要牢牢把握。我們還介紹了如何根據(jù)多個鍵值進行連接,并簡要介紹了半連接和反連接的概念和操作方法。需要注意的是,當進行復雜連接時,一定要用by參數(shù)指定不同表格中用于連接的鍵,否則容易發(fā)生錯誤。

——————————————

往期精彩:

  • IT男,程序猿在婚戀市場有多受歡迎?

  • 都挺好,怎么好?

  • 史上最污技術(shù)解讀,讓你秒懂IT術(shù)語

  • R語言中文社區(qū)2018年終文章整理(作者篇)

  • R語言中文社區(qū)2018年終文章整理(類型篇)

總結(jié)

以上是生活随笔為你收集整理的left join 不重复_R语言ETL工程:连接(join)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。