编程笔记6-dplyr常用语法

2022-07-12  本文已影响0人  江湾青年

引言

一直以来都听闻tidy-r是使R语言起死回生的存在,尽管没有系统学习过,但已经在coding中潜移默化的使用了许多tidy语法,例如管道符%>%ggplot2等等。最近在处理bed文件时遇到了很多base-r解决起来非常复杂的问题,网上一查都是用dplyr包解决的。因此本文记录一下dplyr的常用语法,希望以后逐渐由base-r向tidy-r过渡。

tidyverse家族

dplyr函数特征

  1. 第一个参数是一个数据框。
  2. 随后的参数描述了如何处理第一个参数中指定的数据框,你可以直接引用数据框中的列,而无需使用 $ 运算符(只需使用列名)。
  3. 函数的返回结果是一个新的数据框
  4. 数据框必须经过正确格式化和注释才能发挥作用。尤其是数据必须整齐。简而言之,每一行应该有一个样本,每一列应该代表那个样本的特征。

筛选行:filter()

filter(flights, month == 1, day == 1)

这里,flights是数据框,“month == 1, day == 1”是筛选条件,默认是且的关系,还可以用其他条件进行筛选:

filter(flights, month == 1 | day == 1)

排序行:arrange()

arrange(flights, year, month, day)
arrange(flights, desc(arr_delay))
# 按arr_delay降序,对观测进行重排

筛选列:select()

select(flights, year, month, day)
select(flights, year:day)
select(flights, -(year:day))
select(flights, time_hour, air_time, everything())

重命名列:rename()

rename(flights, tail_num = tailnum)

添加新列:mutate()

mutate(flights,gain = arr_delay - dep_delay,speed = distance / air_time * 60) 
mutate(flights_sml,gain = arr_delay - dep_delay,hours = air_time / 60,gain_per_hour = gain / hours)
transmute(flights,gain = arr_delay - dep_delay,hours = air_time / 60,gain_per_hour = gain / hours)

分组分析:group_by() 和 summarize()

summarize(flights, delay = mean(dep_delay, na.rm = TRUE))
> group_by(fig2a,method,benchmark) %>% 
+   summarise(mean = mean(value),
+             num = n()) 

# 输出:
`summarise()` has grouped output by 'method'. You can override using the `.groups` argument.
# A tibble: 28 × 4
# Groups:   method [7]
   method       benchmark          mean   num
   <fct>        <fct>             <dbl> <int>
 1 scMAGIC-atac Accuracy          0.806     3
 2 scMAGIC-atac Average Recall    0.783     3
 3 scMAGIC-atac Average Precision 0.754     3
 4 scMAGIC-atac Mean F1           0.752     3
 5 GLUE         Accuracy          0.822     3
 6 GLUE         Average Recall    0.727     3
 7 GLUE         Average Precision 0.765     3
 8 GLUE         Mean F1           0.725     3
 9 Seurat       Accuracy          0.776     3
10 Seurat       Average Recall    0.666     3
# … with 18 more rows

处理双表格


其他函数


实战

mm10_gene <- read.table('/mdshare/node10/xyx/projects/RNA-editing/reference/genome_bed/mm10/mm10_gene.bed')
mm10_gene %>% 
  as_tibble() %>%                                       # df转tibble
  transmute(gene_name = V6,                             # 新建一个tibble包含列gene_name
            length = V3 - V2) %>%                       # 包含列length为end - start
  group_by(gene_name) %>%                               # 按gene_name分组
  summarise(meanlen = round(mean(length))) %>%          # 计算每组的平均长度
  filter(gene_name %in% rownames(counts_mtx)) ->        # 筛选在query_mtx中的基因名
  counts_mtx_gene_len
counts_mtx_gene_len
counts_mtx <- counts_mtx[counts_mtx_gene_len$gene_name,]
counts_mtx_TPM <- apply(counts_mtx,2,function(col){col/counts_mtx_gene_len$meanlen}) %>% 
  NormalizeData()

总结

初次接触tidyr会感觉函数的形参比较随意,除了第一个参数必须是数据框本身,后续参数都没有严格要求,有的参数还是函数名(例如之前一直不太理解的ggplot2中的aes())。但实际上,这是因为tidyr的语法更多的是面向操作,而我之前使用的基于which()的筛选方法更多的是面向结果。想想网上的tidyr代码头几行为什么通常使用的是df %>% filter() %>% ...,而不是filter(df, ...)?如果使用管道符,就可以感受到最初的df只是一个输入的对象,而后续则是对数据框内的元素进行花式操作。如果这样理解的话就会发现tidyr代码的优雅和易读了。


参考

http://www.360doc.com/content/21/0805/12/73394596_989613319.shtml
https://bookdown.org/rdpeng/rprogdatascience/managing-data-frames-with-the-dplyr-package.html#dplyr-grammar
https://blog.csdn.net/m0_52406014/article/details/123823476

上一篇 下一篇

猜你喜欢

热点阅读