在R里面使用dplyr对表格进行计算、筛选等操作

我的需求:基因表达差异分析结果的表格,每行是一个基因,不同的列分别表示表达值、Fold Change、P value、Q value等信息,如果要根据基因名称筛选出特定的行,或者针对P value进行数据转化并计算出-log10(P value),可以用dplyr进行实现。

下文转载自:omicsgene https://www.omicsclass.com/article/960

转载贴过来之后格式有变化,可读性不如原文了。

=========================================

dplyr软件包是R中功能最强大,最受欢迎的软件包之一。该软件包由最受欢迎的R程序员Hadley Wickham编写,他编写了许多有用的R软件包,如ggplot2,tidyr等。本文包括一些示例和如何使用使用dplyr软件包来清理和转换数据。这是一个关于数据操作和数据处理的完整教程。

什么是dplyr?

dplyr是一个强大的R软件包,用于处理,清理和汇总非结构化数据。简而言之,它使得R中的数据探索和数据操作变得简单快捷。

dplyr有什么特别之处?

软件包“dplyr”包含许多主要使用的数据操作功能,例如应用过滤器,选择特定列,排序数据,添加或删除列以及聚合数据。这个包的另一个最重要的优点是学习和使用dplyr函数非常容易。也很容易回想起这些功能。例如,filter()用于过滤行。dplyr函数处理速度比基本R函数快。 这是因为dplyr函数是以计算有效的方式编写的。 它们在语法上也更稳定,并且比向量更好地支持数据帧。以下是该包中的方法与用途:

dplyr FunctionDescriptionEquivalent SQL

select()Selecting columns (variables)SELECT

filter()Filter (subset) rows.WHERE

group_by()Group the dataGROUP BY

summarise()Summarise (or aggregate) data-

arrange()Sort the dataORDER BY

join()Joining data frames (tables)JOIN

mutate()Creating New VariablesCOLUMN ALIAS

dplyr中主要方法的使用

filter系列:筛选出自己想要的数据

#安装与加载包

#直接使用内置的iris、mtcars数据集来演示

#iris数据集中,筛选Species为“setosa”,并且Sepal.Length大于5的样本

#"&"也可以替换成“,”

>filter(iris, Species =="setosa"& Sepal.Length >= 5.5)

Sepal.Length Sepal.Width Petal.Length Petal.Width Species

1          5.8         4.0          1.2         0.2  setosa

2          5.7         4.4          1.5         0.4  setosa

3          5.7         3.8          1.7         0.3  setosa

4          5.5         4.2          1.4         0.2  setosa

5          5.5         3.5          1.3         0.2  setosa

filter支持以下几种判断形式:

关系类型:<、 <= 、 >、 >=、==、!=、is.na()、 !is.na()

&、 |、 !、 xor() #针对向量集的操作判断

between()、%in%、 near() #sqrt(2) ^ 2 == 2 返回FALSE,near(sqrt(2) ^ 2, 2)则TRUE

all_vars()、any_vars() #出现于filter_all、filter_at、filter_if中,作为判断条件

filter系列,还有几个变异函数:filter_all、filter_at、filter_if

#筛选任何变量>150的样本

filter_all(mtcars, any_vars(. > 150))

#筛选变量以“d”结尾,并且变量 "%%2" 等于0

filter_at(mtcars, vars(starts_with("d")), any_vars((. %% 2) == 0))

# 筛选变量向下取整 == 原变量数值, 并且这部分变量的数值!= 0 的样本集

filter_if(mtcars, ~ all(floor(.) == .), all_vars(. != 0))

更多用法:

mtcars %>% filter_all(all_vars(.>150)) %>% head() # 筛选所有变量均大于150的行,结果为空

mtcars %>% filter_all(any_vars(.>150)) %>% head() # 筛选存在变量大于150的行,

# 针对变量名称为d开头的所有列,筛选存在变量能整除2的所有行

mtcars %>% filter_at(vars(starts_with("d")), any_vars((.%% 2) == 0))

# 针对变量全为整数的列,筛选所有变量非0的所有行

mtcars %>% filter_if(~all(floor(.) == .), all_vars(.!= 0))

# 支持purrr语法筛选

mtcars %>% filter_at(vars(hp, vs), ~ .%% 2 == 0) # 筛选hp和vs变量都是偶数的所有行

select 函数:仅保留你所需要的列,并支持修改变量名称

用法:select(.data, …)

与之前讲解的filter有所不同,select是筛选变量的,而filter是筛选样本集。

应用场景:假设数据存于宽表中(比如有100个变量的表),而你仅需要其中几个变量。而select的关键在于”…“的判断条件

 #mtcars数据集中,筛选mpg、cyl、wt、vs,4个变量数据

#mtcars[,c("mpg","cyl","wt","vs")],可以实现相同的功能

 >select(mtcars,c("mpg","cyl","wt","vs"))

mpg cyl    wt vs

21.0   6 2.620  0

21.0   6 2.875  0

22.8   4 2.320  1

#

Tips:select 同样支持":"与"-"操作

#比如:select(mtcars,c("mpg":"vs"))、表示连续的列选择

#select(mtcars,-"mpg") 删除mpg列

以上给人感觉,不通过select,利用数据框与向量操作,同样可以做到,select 真正强大的地方在于,支持以下几种条件判断:

包含关系:starts_with()、 ends_with()、 one_of()

匹配关系:matches()、contains()、num_range()

# 包含关系:在Iris中,筛选以Petal开头,或Width结尾的变量

>select(iris, starts_with("Petal"), ends_with("Width"))

#   Petal.Length Petal.Width Sepal.Width

#         1.4         0.2         3.5

#         1.4         0.2         3.0

#         1.3         0.2         3.2

# ...(数据省略)

#Tips:starts_with("Petal"), ends_with("Width"),2个条件不是"且"的关系,而是"或"

#

 包含关系:经常需要提取变化的数据集合,利用one_of再合适不过了

#提取mtcars中,"mpg","cyl","wt","vs","vss"

 >var1 <- c("mpg","cyl","wt","vs","vss")

 >select (mtcars, one_of(var1))

# mpg cyl    wt vs

# 21.0   6 2.620  0

# 21.0   6 2.875  0

# 2.8   4 2.320  1

# ...(省略数据)

# Warning message: Unknown columns: `vss` 

# Tips: select没找到额变量,系统会返回警告

#

匹配关系:筛选Iris数据集,变量名中带有"wid"的变量名

>select(iris, matches(".wid."))

>select(iris, contains("wid"))

#   Sepal.Width Petal.Width

#        3.5         0.2

#        3.0         0.2

#

 num_range能高效匹配变量名称类似x01, x02, x03的

# 随机数据框,由X1~X5,y 组成:

df <- data.frame(x1= runif(10), x2= runif(10),

x3= runif(10), x4= runif(10),

x5= runif(10), y= letters[1:10])

#

 筛选 y, x1:x3的变量,并且把y重命名为 var1

>select(df, c(var1 ="y", num_range("x", 1:3)))

#  var1  x1         x2        x3

#  a 0.96631605 0.29815009 0.6545414

#  b 0.61046600 0.76547552 0.8247191

#  c 0.70510879 0.46636723 0.4472588

# ... (数据省略)

mutate系列:对数据进行计算产生新数据

用法:mutate(.data, …)

mutate的使用方式,主要是依靠"…"的公式变化,生成新的变量

mutate支持以下几种公式 :

+、-、*、÷ 、%%、%|% 等常用计算方式

lead()、 lag()

dense_rank(), min_rank(), percent_rank(), row_number(), cume_dist(), ntile()

cumsum(), cummean(), cummin(), cummax(), cumany(), cumall()

na_if(), coalesce()

if_else(), recode(), case_when()

先从"rank"系列开始介绍,这一函数类,主要是用来划分名次、等级、百分比、密度等等

#############简单的+、-、*、÷ 、%%、%|%   可以增加新的数据列

 >mutate(mtcars,aa=hp-drat,bb=mpg*cyl)

mpg cyl  disp  hp drat    wt  qsec vs am gear carb     aa    bb

1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 106.10 126.0

2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 106.10 126.0

3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1  89.15  91.2

4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 106.92 128.4

5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 171.85 149.6

6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 102.24 108.6

7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 241.79 114.4

#

######如果只想保留这些新的变量可以:

> transmute(mtcars,aa=hp-drat,bb=mpg*cyl)

aa    bb

1  106.10 126.0

2  106.10 126.0

3   89.15  91.2

4  106.92 128.4

5  171.85 149.6

6  102.24 108.6

#

#########percent_rank,按照[0,1]百分比的形式进行排序

# 举例说明,按照x的数值,按照百分比进行划分

x <- c(5, 1, 3, 2, 4)

percent_rank(x)

# [1] 1.00 0.00 0.50 0.25 0.75

# 这类函数比较适用于 ,需要排名次的场景。比如考试、比赛...

#

  比如根据iris中的Sepal.Length,进行百分比表示, 其中 %>% 管道的标识符,select函数中,everything()可以用来更换变量顺序 

>iris %>% mutate(Length_rank = percent_rank(Sepal.Length)) %>% select(Length_rank,everything()) 

#

   Length_rank Sepal.Length Sepal.Width Petal.Length Petal.Width Species

#   0.21476510          5.1         3.5          1.4         0.2  setosa

#   0.10738255          4.9         3.0          1.4         0.2  setosa

#   ...(数据省略)

#

 row_number(),不仅可以用来对想来排序,也可以表示获取行数

mutate(mtcars, row_number() == 1L) # 新生成的变量,用来判断是否是第一行,返回TRUE 或者 FALSE

mtcars %>% filter(between(row_number(), 1, 10)) # 通过row_number,筛选1-10行.有点类似 top_n(10)

#

 ntile,切割数据集为N块,返回具体的数值,属于等分切割

ntile(runif(10), 5)

# [1] 1 2 4 5 5 3 4 2 3 1

# 某种程度上,ntile可以用来划分训练集和测试集(类似sample函数) 

# ind <- sample(2, nrow(mtcars), replace = TRUE, prob = c(0.8,0.2))

# mtcars[ind == 1,]

# 备注:ntile对数据框使用的时候,如果没有特殊标明具体的数据列,ntile会对所有的列进行切割操作

再说一下"cum"函数系列,这类函数计算累积指标,比如截止到某一天的平均值、总和、乘积等等。

# cumsum,累积相加的数值

cumsum(1:10)

#13610152128364555

# 原数据集有N个,返回也是N个

# 类似MS_SQL中的sum(s)over(order by y)

# cumany(), cumall(),则是逻辑判断,并非计算数值

cumall(-5:5)

#TRUETRUETRUETRUETRUEFALSEFALSEFALSEFALSEFALSEFALSE

# 返回的是逻辑值,0代表FALSE

最后说一下"判断"函数系列,这类函数应用比较广泛。

比如生活中,当天空下雨了,小明就打伞了

类似EXCEL中的 if函数,vlookup函数等等

# if_else

# 用法:if_else(condition, true, false, missing = NULL),比传统的ifelse多了一个missing参数

# 并且if_else能保留原数据的数据类型,不会降维操作

# 假设x >= 0,则 y-1,y < 0 的情况下, y + 1 

df <- data.frame(x = c(-5:4), y = runif(10))

df %>% mutate( xy = if_else(x >=0, y -1, y+1, y))

#     x         y         xy

#   -5    0.7760150  1.7760150

#   -4    0.9310976  1.9310976

# case_when中,判断的条件可以更加的多样化

# case_when,与SQL中的case...when...一样

# 同C语言中的switch一样   

x <- c(1:10,NA)

case_when(

x %%2==0~"偶",

x %%2==1~"奇",

TRUE~ as.character(x)

#可以设置一个默认值

)

"奇""偶""奇""偶""奇""偶""奇""偶""奇""偶"NA

arrange 用于数据排序

arrange() 函数以行为单位进行排序,默认为升序排列,降序使用 desc( ) 函数。第一个参数为数据集名称,后面为排序依据变量。

>arrange(mtcars,hp,mpg,cyl)

mpgcyldisphpdratwtqsecvsamgearcarb

1  30.44  75.752 4.931.61518.521  1    4    2

2  24.44 146.762 3.693.19020.001  0    4    2

3  33.94  71.165 4.221.83519.901  1    4    1

4  27.34  79.066 4.081.93518.901  1    4    1

5  32.44  78.766 4.082.20019.471  1    4    1

6  26.04 120.391 4.432.14016.700  1    5    2

7  22.84 108.093 3.852.32018.611  1    4    1

8  22.84 140.895 3.923.15022.901  0    4    2

9  21.54 120.197 3.702.46520.011  0    3    1

10 18.16 225.0105 2.763.46020.221  0    3    1

多列排序,降序用desc()

>arrange(mtcars,desc(hp),mpg,cyl)

mpgcyldisphpdratwtqsecvsamgearcarb

1  15.08 301.0335 3.543.57014.600  1    5    8

2  15.88 351.0264 4.223.17014.500  1    5    4

3  13.38 350.0245 3.733.84015.410  0    3    4

4  14.38 360.0245 3.213.57015.840  0    3    4

5  14.78 440.0230 3.235.34517.420  0    3    4

6  10.48 460.0215 3.005.42417.820  0    3    4

7  10.48 472.0205 2.935.25017.980  0    3    4

8  15.28 275.8180 3.073.78018.000  0    3    3

9  16.48 275.8180 3.074.07017.400  0    3    3

10 17.38 275.8180 3.073.73017.600  0    3    3

sample_n() and sample_frac()按行随机选取数据子集

sample_n() and sample_frac() 分别是按固定多少行随机选取,一个是按行数的比例选取;

>sample_n(mtcars,10)

mpgcyldisphpdratwtqsecvsamgearcarb

1  18.78 360.0175 3.153.44017.020  0    3    2

2  14.38 360.0245 3.213.57015.840  0    3    4

3  21.54 120.197 3.702.46520.011  0    3    1

4  32.44  78.766 4.082.20019.471  1    4    1

5  26.04 120.391 4.432.14016.700  1    5    2

6  19.26 167.6123 3.923.44018.301  0    4    4

7  17.86 167.6123 3.923.44018.901  0    4    4

8  27.34  79.066 4.081.93518.901  1    4    1

9  15.88 351.0264 4.223.17014.500  1    5    4

10 15.58 318.0150 2.763.52016.870  0    3    2

>sample_frac(mtcars,0.1)

mpgcyldisphpdratwtqsecvsamgearcarb

1 10.48  472 205 2.935.2517.980  0    3    4

2 14.38  360 245 3.213.5715.840  0    3    4

3 13.38  350 245 3.733.8415.410  0    3    4

%>% 数据管道综合运用举例

data(iris)

data(mtcars)

iris %>% head()

mtcars %>% head()

# 筛选变量名为字符串开头的变量

iris %>%select(starts_with("Sepal")) %>% head()

# 多个筛选条件

iris %>%select(-starts_with("Sepal")) %>% head()

# 筛选变量名为字符串结尾的变量

iris %>%select(ends_with("Length")) %>% head()

iris %>%select(-ends_with("Length")) %>% head()

# 将变量Species移动到最前面

iris %>%select(Species, everything()) %>% head()

# 反筛选,筛选除了Sepal.Length变量的其它变量

iris %>%select(-Sepal.Length) %>%head()

# 将变量Species移动到最后面

iris %>%select(everything(), Species) %>% head()

iris %>%select(-Species, Species) %>% head()

# 错误的用法,结果为空

iris %>%select(Species, -Species) %>% head()

iris %>%select(contains("etal")) %>% head()

iris %>%select(matches(".t.")) %>% head()# 筛选名称中,t在中间的变量。  

iris %>%select(last_col()) %>% head()# 最后一个变量

iris %>%select(last_col(offset =2)) %>% head()# 倒数第3个变量

iris %>%select(one_of(c("Petal.Length","Petal.Width"))) %>% head()

iris %>% group_by(Species) %>%select(group_cols()) %>% distinct() %>% head()# 获取分组变量名

df <-as.data.frame(matrix(runif(100), nrow =10)) %>% as_tibble()

head(df)

df %>%select(V4:V7) %>% head()# 筛选V4列到V7列

df %>%select(num_range("V",4:7)) %>% head()# 结果与前面一样

#列名重命名

iris %>%select(petal_length = Petal.Length) %>% head()# 重命名

iris %>%select(obs = starts_with('S')) %>% head()# 多个变量重命名

-END-

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容