原文鏈接:https://mp.weixin.qq.com/s/ldO0rm3UM_rqlFnU3euYaA
2020年,開封 《R 數據科學》R for data science,系統學習R 數據處理。
在一個典型的數據科學項目中,需要的工具模型大體如下圖所示。 ---R for Data Science
之前的推文講了一些生信常見圖形的繪制(后續會一直補充),現在開始主要依據《R數據科學》一書逐漸介紹數據分析的過程。
本次根據 msleep
數據集,盤一盤“列”的操作。
一 載入數據和R包
#載入R包
#install.packages("tidyverse")
library("tidyverse")
#查看內置數據集
head(msleep,2)
# A tibble: 6 x 11
name genus vore order conservation sleep_total sleep_rem sleep_cycle awake
<chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 Chee~ Acin~ carni Carn~ lc 12.1 NA NA 11.9
2 Owl ~ Aotus omni Prim~ NA 17 1.8 NA 7
# ... with 2 more variables: brainwt <dbl>, bodywt <dbl>
上述數據集有11列(變量),而生信中的臨床信息,實驗室檢驗指標經常上百,基因(突變,表達)信息更是成千上萬。此時可以基於變量名,使用select() 函數快速生成一個有用的變量子集。
二 以列之名
2.1 選擇對應名稱列
使用select()直接選擇列名稱所對應的列。
#選擇name, sleep_total ,awake三列,使awake在中間
msleep %>%
select(name, awake, sleep_total) %>% head()
彩蛋:添加順序即為輸出順序。
2.2 選擇若干連序列
使用start_col:end_col
語法選擇若干的連續列。
msleep %>%
select(name:vore, sleep_total:awake) %>% head(2)
# A tibble: 6 x 7
name genus vore sleep_total sleep_rem sleep_cycle awake
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 Cheetah Acinonyx carni 12.1 NA NA 11.9
2 Owl monkey Aotus omni 17 1.8 NA 7
與基本語法類似,:
用來選擇連續的列。
2.3 根據部分列名稱選擇列
如果列名結構相似,可使用starts_with()
,ends_with()
, contains()
完成部分匹配。
1)starts_with()
選擇以“XX”開頭的所有列
msleep %>%
select(name, starts_with("sleep")) %>% head(2)
# A tibble: 2 x 4
name sleep_total sleep_rem sleep_cycle
<chr> <dbl> <dbl> <dbl>
1 Cheetah 12.1 NA NA
2 Owl monkey 17 1.8 NA
2)ends_with()
選擇以“XX”結尾的所有列
msleep %>%
select(ends_with("e")) %>% head(2)
# A tibble: 2 x 4
name vore sleep_cycle awake
<chr> <chr> <dbl> <dbl>
1 Cheetah carni NA 11.9
2 Owl monkey omni NA 7
3) contains()
選擇包含“XX”的所有列
msleep %>%
select(contains("leep")) %>% head(2)
# A tibble: 2 x 3
sleep_total sleep_rem sleep_cycle
<dbl> <dbl> <dbl>
1 12.1 NA NA
2 17 1.8 NA
4)matches()
選擇基於正則的列
如果列名模式不相似,使用matches()
選擇對應正則表達式的列。
#選擇任何包含“a”,后跟一個或多個其他字母和“e”的列
msleep %>%
select(matches("a.+e")) %>% head(2)
# A tibble: 2 x 2
name awake
<chr> <dbl>
1 Cheetah 11.9
2 Owl monkey 7
三 邏輯之名
3.1 基於數據類型選擇列
使用select_if()
選擇所有數值列select_if(is.numeric)
,此外還可用is.numeric
, is.integer
,is.double
,is.logical
,is.factor
。
msleep %>%
select_if(is.numeric) %>% head(2)
# A tibble: 2 x 6
sleep_total sleep_rem sleep_cycle awake brainwt bodywt
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 12.1 NA NA 11.9 NA 50
2 17 1.8 NA 7 0.0155 0.48
3.2 基於邏輯表達式選擇列
msleep %>%
select_if(is.numeric) %>%
select_if(~mean(., na.rm=TRUE) > 10) %>% head(2)
# A tibble: 2 x 3
sleep_total awake bodywt
<dbl> <dbl> <dbl>
1 12.1 11.9 50
2 17 7 0.48
注:select_all / if
函數要求將函數作為參數傳遞。因為mean > 10 本身不是函數,所以需要前面添加“~”表示匿名函數;或者使用funs()
先將函數包裝。
more_than_10 <- function(x) {
mean(x,na.rm=TRUE) > 10
}
msleep %>% select_if(is.numeric) %>% select_if(more_than_10) %>% head(2)
# A tibble: 2 x 3
sleep_total awake bodywt
<dbl> <dbl> <dbl>
1 12.1 11.9 50
2 17 7 0.48
結果同上。
msleep %>%
select_if(~is.numeric(.) & mean(., na.rm=TRUE) > 10) %>% head(2)
結果同上!
3.3 選擇唯一值數目符合條件的列
結合 n_distinct()
選擇具有不少於20個不同答案的列。
msleep %>%
select_if(~n_distinct(.) >= 20) %>% head(2)
# A tibble: 2 x 8
name genus sleep_total sleep_rem sleep_cycle awake brainwt bodywt
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Cheetah Acinonyx 12.1 NA NA 11.9 NA 50
2 Owl monkey Aotus 17 1.8 NA 7 0.0155 0.48
四 調整列順序
4.1 選擇列名稱時候直接調整
#選擇name, sleep_total ,awake三列,使awake在中間
msleep %>%
select(name, awake, sleep_total) %>% head(2)
4.2 everything()
返回未被選擇的所有列
當只是將幾列移到最前面,后面的可使用everything(),節省大量輸入時間。
msleep %>%
select(conservation, everything()) %>% head(2)
# A tibble: 2 x 11
conservation name genus vore order sleep_total sleep_rem sleep_cycle awake
<chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 lc Chee~ Acin~ carni Carn~ 12.1 NA NA 11.9
2 NA Owl ~ Aotus omni Prim~ 17 1.8 NA 7
# ... with 2 more variables: brainwt <dbl>, bodywt <dbl>
五 更改列名字
5.1 select
更改列名
msleep %>%
select(animal = name, sleep_total) %>% head(2)
# A tibble: 2 x 2
animal sleep_total
<chr> <dbl>
1 Cheetah 12.1
2 Owl monkey 17
注:select語句中更改,只留下select的列。
5.2 rename更改列名
msleep %>%
rename(animal = name) %>% head(2)
# A tibble: 2 x 11
animal genus vore order conservation sleep_total sleep_rem sleep_cycle awake
<chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 Cheet~ Acin~ carni Carn~ lc 12.1 NA NA 11.9
2 Owl m~ Aotus omni Prim~ NA 17 1.8 NA 7
# ... with 2 more variables: brainwt <dbl>, bodywt <dbl>
以上兩種方式注意區分!
5.3 重新格式化所有列名
1)select_all()
函數允許更改所有列,並以一個函數作為參數。
msleep %>%
select_all(toupper) %>% head(2)
# A tibble: 2 x 11
NAME GENUS VORE ORDER CONSERVATION SLEEP_TOTAL SLEEP_REM SLEEP_CYCLE AWAKE
<chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 Chee~ Acin~ carni Carn~ lc 12.1 NA NA 11.9
2 Owl ~ Aotus omni Prim~ NA 17 1.8 NA 7
# ... with 2 more variables: BRAINWT <dbl>, BODYWT <dbl>
toupper()
使所有列名變成大寫形式,tolower()
變成小寫。
2)創建函數替換
如果輸入文件的列名較混亂,根據需求逐步替換。
msleep2 <- select(msleep, name, sleep_total, brainwt)
colnames(msleep2) <- c("Q1 name", "Q2 sleep total", "Q3 brain weight")
msleep2[1:3,]
# A tibble: 3 x 3
`Q1 name` `Q2 sleep total` `Q3 brain weight`
<chr> <dbl> <dbl>
1 Cheetah 12.1 NA
2 Owl monkey 17 0.0155
3 Mountain beaver 14.4 NA
目的把列名中的"Q1 name"改為"name","Q2 sleep total"改為"sleep_total" ...
A:去掉前面的Q1,Q2,Q3 ;
B:去掉Q1,Q2,Q3 與名稱的空格;
C:sleep total之間的空格使用下划線替換。
msleep2 %>%
select_all(~str_replace(., "Q[0-9]+", "")) %>% #去掉Q1
select_all(~str_replace(., "^ ", "")) %>% #去掉名稱前面的空格
select_all(~str_replace(., " ", "_")) #下划線替換sleep total之間的空格
# A tibble: 83 x 3
name sleep_total brain_weight
<chr> <dbl> <dbl>
1 Cheetah 12.1 NA
2 Owl monkey 17 0.0155
搞定!
六 滿五贈二
6.1 刪除某些列
選擇的列前用“-”即可,函數用法與選擇一致。
msleep %>%
select(-(name:genus), -conservation,-(ends_with("e"))) %>% head(2)
# A tibble: 2 x 5
order sleep_total sleep_rem brainwt bodywt
<chr> <dbl> <dbl> <dbl> <dbl>
1 Carnivora 12.1 NA NA 50
2 Primates 17 1.8 0.0155 0.48
6.2 行名稱改為第一列
某些數據框的行名並不是列,例如mtcars數據集:
mtcars %>% head(2)
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
使用 rownames_to_column()
函數,行名改為列,且可指定列名稱。
mtcars %>%
tibble::rownames_to_column("car_name") %>% head(2)
car_name mpg cyl disp hp drat wt qsec vs am gear carb
1 Mazda RX4 21 6 160 110 3.9 2.620 16.46 0 1 4 4
2 Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
相信我,后面做數據鏈接(join)的時候,你會很希望行名是具體列的。
參考資料
《R數據科學》
https://r4ds.had.co.nz/introduction.html
https://suzanbaert.netlify.com/2018/01/dplyr-tutorial-1/
數據處理確實不如可視化“好玩”,但是可視化的數據大多都需要前期處理,這個“檻”一起慢慢跨過去!
◆ ◆ ◆ ◆ ◆
【覺得不錯,右下角點個“在看”,期待您的轉發,謝謝!】