R語言筆記-dplyr-2-表操作

2021-03-02 宇飛的世界

表操作基礎多表操作列操作基本操作多種函數功能當前列行操作構造數據集行匯總統計分組操作添加分組刪除分組變量動詞

前文:

R語言筆記-dplyr-1-基礎篇

表操作

指像sql中的left join,inner join等表格之間的操作,或者是Excel中Power Piovt建模的建立關係,從而實現不同表格間的關聯

表格中的列操作,如列求和,均值等

行操作指不同欄位間的計算,如Excle的列與列之間計算,Excle中的函數對行列不敏感,沒有明顯區別,但是R中tidyverse裡列計算簡單,行間計算依賴rowwise()函數實現

基礎

left_join(),full_join,inner_join()等動詞關聯兩個表。詳情請查看:vignette("two-table"),在R中執行。

left_join()實現類似Excel中VLOOKUP函數功能或資料庫中left join功能,將「右表」的欄位依據「主鍵」關聯到「左表」上。

left_join(),right_join(),full_join(),inner_join(),第一個以左表為主,第二個右表為主,第三個全連接,第四個內連接(只返回兩表中都有的記錄),和資料庫中連接方式一致。

默認會自動尋找兩表中相同的欄位名作為關聯的條件

library("nycflights13")
# Drop unimportant variables so it's easier to understand the join results.
flights2 <- flights %>% select(year:day, hour, origin, dest, tailnum, carrier)

flights2 %>%
 left_join(airlines)

指定關聯條件列,類似資料庫中on a.column = b.column

flights2 %>% left_join(planes, by = "tailnum")

left_join(x,y,by = c("a" = "b", "c" = "d")) 將會匹配 x$a to y$b 和 x$c to y$d 作為關聯條件

#出發機場和目的機場信息
flights2 %>% left_join(airports, by = c("dest" = "faa"))
#flights2 %>% left_join(airports, c("origin" = "faa"))
# 組合條件 多條件時用向量包裹即可c("dest" = "faa","cola" = "colb"))

anti_join() 刪除所有左表中在右表中匹配到的行

semi_join()保留所有左表在右表中匹配到的行

df1 <- tibble(a=letters[1:20],b=1:20)
df2 <- tibble(a=letters,b=1:26)

df1 %>% semi_join(df2)
df2 %>% anti_join(df1)

intersect(x,y)返回x,y交集

union(x,y)返回x,y中唯一的值

setdiff(x,y)返回存在x中但是不存在y中的記錄

(df1 <- tibble(x = 1:2, y = c(1L, 1L)))
(df2 <- tibble(x = 1:2, y = 1:2))
intersect(df1, df2)
union(df1, df2)
setdiff(df1, df2)
setdiff(df2, df1)

多表操作

多表操作請使用purrr::reduce(),當需要合併多個表格時,可用以下方式減少合併代碼量。

dt1 <- data.frame(x = letters)
dt2 <- data.frame(x = letters,cola = 1:26)
dt3 <- data.frame(x = letters,colb = 1:26)
dt4 <- data.frame(x = letters,cold = 1:26)
dt5 <- data.frame(x = letters,cole = 1:26)

dtlist <- list(dt1,dt2,dt3,dt4,dt5)
purrr::reduce(dtlist,left_join,by='x')


列操作

在多列上執行相同的操作是常用的操作,但是通過複製和粘貼代碼,麻煩不說還容易錯:

df %>% 
 group_by(g1, g2) %>%
 summarise(a = mean(a), b = mean(b), c = mean(c), d = mean(d))

通過across()函數可以更簡潔地重寫上面代碼:

df %>% 
 group_by(g1, g2) %>%
 summarise(across(a:d, mean))

基本操作

across() 有兩個主要參數:

starwars %>% 
summarise(across(where(is.character), ~ length(unique(.x))))

# 列屬性是字符的列求唯一值數
# starwars %>%
# summarise(length(unique(name)))
# starwars %>%
# summarise(length(unique(hair_color)))

starwars %>%
group_by(species) %>%
filter(n() > 1) %>%
summarise(across(c(sex, gender, homeworld), ~ length(unique(.x))))

starwars %>%
group_by(homeworld) %>%
filter(n() > 1) %>%
summarise(across(where(is.numeric), ~ mean(.x, na.rm = TRUE)))

across() 不會選擇分組變量:

df <- data.frame(g = c(1, 1, 2), x = c(-1, 1, 3), y = c(-1, -4, -9))
df %>%
group_by(g) %>%
summarise(across(where(is.numeric), sum))

多種函數功能

通過在第二個參數提供函數或lambda函數的命名列表,可是使用多個函數轉換每個變量:

min_max <- list(
min = ~min(.x, na.rm = TRUE),
max = ~max(.x, na.rm = TRUE)
)
starwars %>% summarise(across(where(is.numeric), min_max))

通過.names參數控制名稱:

NB:該參數的機制沒有特別理解,需多練習體會。主要是運用到匿名函數時

以下是官方圖冊中的案例,但是報錯:

starwars %>% summarise(across(where(is.numeric), min_max, .names = "{.fn}.{.col}"))

修改後正常運行:

starwars %>% summarise(across(where(is.numeric), min_max, .names = "{fn}.{col}"))

區別主要是.names參數的使用方式問題,.加不加的問題。

starwars %>% summarise(across(where(is.numeric), min_max, .names = "{fn}——{col}"))

當前列

如果需要,可以通過調用訪問內部的「當前」列的名稱cur_column()。

該函數不是特別容易理解,需要多嘗試使用加深認識。

df <- tibble(x = 1:3, y = 3:5, z = 5:7)
mult <- list(x = 1, y = 10, z = 100)

df %>% mutate(across(all_of(names(mult)), ~ .x * mult[[cur_column()]]))


行操作

在操縱數據框中,dplyr等工具讓我們對列操作相對簡單,但是對行操作則困難些。

構造數據集
df <- tibble(x = 1:2, y = 3:4, z = 5:6)
df %>% rowwise()

像group_by(),rowwise()並沒有做任何事情,它的作用是改變其他動詞的工作方式:比較以下代碼

df %>% mutate(m = mean(c(x, y, z)))
df %>% rowwise() %>% mutate(m = mean(c(x, y, z)))

data.table中的操作:

library(data.table)

dt <- data.table(x = 1:2, y = 3:4, z = 5:6)
dt[,m:=mean(c(x,y,z))][]
dt[,m:=mean(c(x,y,z)),by=.(x)][]

您可以選擇在調用中提供「標識符」變量rowwise()。這些變量在您調用時被保留summarise(),因此它們的行為與傳遞給的分組變量有些相似group_by():

df <- tibble(name = c("Mara", "Hadley"), x = 1:2, y = 3:4, z = 5:6)

df %>%
rowwise() %>%
summarise(m = mean(c(x, y, z)))

df %>%
rowwise(name) %>%
summarise(m = mean(c(x, y, z)))

行匯總統計

dplyr::summarise()使得匯總一列中各行的值非常容易。當與之結合使用時rowwise(),還可以輕鬆匯總一行中各列的值:

df <- tibble(id = 1:6, w = 10:15, x = 20:25, y = 30:35, z = 40:45)
rf <- df %>% rowwise(id)
rf %>% mutate(total = sum(c(w, x, y, z)))
rf %>% summarise(total = sum(c(w, x, y, z)))

鍵入每個變量名稱很繁瑣,通過c_across()使更簡單

rf %>% mutate(total = sum(c_across(w:z)))
rf %>% mutate(total = sum(c_across(where(is.numeric))))

rf %>%
mutate(total = sum(c_across(w:z))) %>%
ungroup() %>%
mutate(across(w:z, ~ . / total))


分組操作

詳情: https://cloud.r-project.org/web/packages/dplyr/vignettes/grouping.html

group_by()最重要的分組動詞,需要一個數據框和一個或多個變量進行分組:

添加分組
by_species <- starwars %>% group_by(species)
by_sex_gender <- starwars %>% group_by(sex, gender)

除了按照現有變量分組外,還可以按照函數處理後的變量分組,等效在mutate()之後執行group_by:

bmi_breaks <- c(0, 18.5, 25, 30, Inf)
starwars %>%
group_by(bmi_cat = cut(mass/(height/100)^2, breaks=bmi_breaks)) %>%
tally()

刪除分組變量

要刪除所有分組變量,使用ungroup():

by_species %>%
ungroup() %>%
tally()

動詞

summarise() 計算每個組的匯總,表示從group_keys開始右側添加匯總變量

by_species %>%
summarise(
n = n(),
height = mean(height, na.rm = TRUE)
)

該.groups=參數控制輸出的分組結構。刪除右側分組變量的歷史行為對應於.groups = "drop_last"沒有消息或.groups = NULL有消息(默認值)。

從1.0.0版開始,分組信息可以保留(.groups = "keep")或刪除 (.groups = 'drop)

a <- by_species %>%
summarise(
n = n(),
height = mean(height, na.rm = TRUE),.groups='drop') %>%
group_vars()

b <- by_species %>%
summarise(
n = n(),
height = mean(height, na.rm = TRUE),.groups='keep') %>%
group_vars()

object.size(a)
object.size(b)

在實際使用中,當數據較大時需要刪掉分組信息。以上可以看到保留分組信息的比沒保留的大了兩倍多。

相關焦點

  • R語言 | 數據操作dplyr包
    [更新~] Python網絡爬蟲與文本數據分析公眾號只帶著Python字眼,卻分享著R語言,不務正業,任性了~dplyr簡介dplyr是R語言的數據分析包,很像python中的pandas,能對dataframe
  • 《實習日記》| 7月20日 R語言筆記——dplyr
    7月20日R語言筆記——dplyr7月20日R語言筆記——dplyr五個基礎函數1.mutate(),新增列2.select
  • 【R學習筆記】- 數據整形 - dplyr and tidyr
    dplyr包裡的group_by()和summarise(),這兩個函數我用過,tidyr包沒接觸過,但接觸過類似裡面的gather()、spread
  • R語言點滴:dplyr函數與查重案例(1)
    微信公眾號:醫意貫之如有問題或建議,請公眾號留言;如果你覺得該文章對你有幫助,歡迎讚賞R語言點滴
  • R語言基於dplyr實現數據快捷操作
    R語言在處理大數據方面一直是被人詬病的地方,那麼有人就為R語言打造了一個dplyr包可以實現高效的數據預處理,減少內存的消耗,提升處理效率
  • dplyr和tidyr簡介|數據處理
    數據處理兩大利器:dplyr和tidyr1 dplyr 簡介dplyr是Hadley Wickham
  • R語言dplyr包學習筆記(吐血整理宇宙無敵詳細版) - CDA數據分析師
    出處:AI入門學習dplyr包主要用於數據清洗和整理,主要功能有:行選擇、列選擇、統計匯總、窗口函數、數據框交集等是非常高效、友好的數據處理包,學清楚了,基本上數據能隨意玩弄,對的,隨意玩弄,簡直大大提高數據處理及分析效率。我以為,該包是數據分析必學包之一。學習過程需要大量試驗,領悟其中設計的精妙之處。
  • 『R腳本練習』dplyr各種join
    dplyr 各種joinvlookup 其實就是給定一個index,或者說key,然後把另一個表裡關於這個key的內容找到具體操作:EXCEL入門必學的VLOOKUP函數相信我你終於可以學會了如果把表1看成left,表2看成right, 那麼所謂left_join就是保證表1的key的順序和數量不變,把表2中和表1-key對應的value3, value4給合併過來,如果表2中沒有key中某一個值
  • 【數據管理】Tidyverse:R 語言學習之旅的新起點
    2 您用tidyverse包嗎?作為起點的路徑則是近年新興的學習模式(tidyverse first),理念是在一開始先不談[] 、[[]] 、$ 流程控制與循環等內容,而從dplyr 的函數應用開頭,目的是在最短時間讓初學者切入數據處理與視覺化的應用,讓R 語言能夠很快地在課業、研究或者工作派上用場。
  • 對照著Excel入門R語言表格數據處理
    #在線安裝dplyr包;#install.packages("dplyr")#載入dplyr包;library(dplyr)#改變工作目錄setwd#mutate()mutate(tb,RNA_FC = 2^RNA_log2FC)mutate(tb,Sum = RNA_log2FC+Ribo_log2FC)當然也可以使用apply()基礎函數:對矩陣、數據框所有的行或列(1表示按行,2表示按列)進行計算。
  • Datacamp學習筆記(1)——R語言中的Tidyverse
    今天就是學習筆記的第一部分,TIDYVERSE!也推薦大家也可以用TIDYVERSE來對自己的實驗數據進行一下整理和可視化。給大家看一個實例,感受一下經過整理和可視化的數據。1# 載入gapminder數據2library(gapminder)34# 載入dplyr包5library(dplyr)67# 查看gapminder8gapminder       現在數據和包都加加載好了,看一下gapminder長啥樣!
  • R包之dplyr--處理表格數據的好幫手
    在R語言做生信分析的過程中,前期有相當一部分工作都是在處理各種表格--刪除某列、改列名、加某一列、根據條件篩選某些列 -- 幾乎左右的生信分析項目都離不開數據框的處理
  • 「R」dplyr 行式計算
    「原文來自:dplyr 文檔」上一篇:「R」dplyr 列式計算通常 dplyr 和 R 更適合對列進行操作,而對行操作則顯得更麻煩。;dbl [1]>     1#> 2 <int [2]>     2#> 3 <int [3]>     3但如果只寫 length(x) dplyr 就能算出 x中 元素的長度不是很好嗎?
  • 從另一個視角看 R 語言的方言 Tidyverse
    我向我的學生們高度讚揚 RStudio 公司,我使用並推薦 Hadley 的包 ggplot2 和 stringr (均不屬於 Tidyverse),有時 devtools 確實節省了我大量時間。換句話說,我並沒有把 RStudio 當作什麼邪惡社團。
  • 數據處理之——dplyr
    dplyr簡介關於R中的數據處理,上期我們介紹了plyr,這期我們接著介紹數據處理相關包dplyr。
  • 寫給零基礎同學的R語言第四篇教程-神奇R包dplyr
    首先還是要下載:install.packages("dplyr")加載:library(dplyr)下面要用到tidyr,所以也加載一下library(tidyr) 一、測試數據1.新建數據框frame1<-data.frame
  • 強大的數據清理大師:dplyr
    今天介紹一款非常受歡迎的、專注於數據清理的R包{dplyr}。本篇文章主要介紹dplyr中的六個關鍵函數,熟練掌握可以大大加速數據清理的過程。...# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1
  • 【好書共享】《R for Data Science》的中譯版
    這本書原版就是開源的(網址:http://r4ds.had.co.nz/),但是中文看得更快,學R語言一定要買一本紙質書放在案頭,多多翻閱。R for Data Science關於這本書這本書將教我們如何用R來做數據科學:學習如何將自己的數據導入R中,把它變成最有用的結構,轉換,可視化並對數據進行建模。
  • rpy2庫 | 在jupyter中調用R語言代碼
    Python勝在幹髒活累活,諸如數據採集、數據清洗、機器學習等;而R語言勝在統計分析、可視化等。所以,如果你正好Python和R都入門了,可以考慮兩者結合。那麼就會遇到今天的問題-如何在jupyter中使用R語言代碼?
  • R語言基因去重code中delete會讓行名改變
    R語言是開放的,開放帶來的功能就是可能在荒野裡開到高速的速度,危險也是並存的。另外也沒有多少不是專門計算機或者程式設計師願意仔細看代碼是怎麼使用的,基本都是「抄」。別人寫的,能用,自己用。那麼想要準確的使用就要在運行完每一步,對數據進行觀察。