学员提了个问题,以下这个GEO的样本名称,处理和对照夹杂,如何获取样本名称呢?

一种方法就是,人工输入,最直接,不过,这里有192个样本。事实上当一件事情重复三次后,就应当停下来想一想,有没有更简单的方法。
肯定有!正则表达式就是做这个事情的啊,我们有一次在做探针id转化的时候已经用过了。
正则表达式是我们认识世界的哲学
但是,在很长一段时间内,我是不会正则表达式的,我用的是tidyr包中的分列,只要不断分和取舍,就能获得想要的列,也就是隐藏着的case和control。

使用tidyr中的separate来处理
那我们就操作一下:
复制信息粘贴为txt,

读入R语言,并且命名。
data <- data.table::fread("gsm_group.txt",data.table = F,header = F)
names(data) <- c("GSM","group")
现在数据是这个样子的:

切割两次,第一次以_blood_
作为分隔符,一分为二,留取后面的内容,再以 _
切割以此,获取前面的内容就可以了
library(dplyr)
library(tidyr)
metadata <- data %>%
separate(group,into = c("drop","group"),sep = "_blood_") %>%
select(-drop) %>%
separate(group,into = c("group","drop"),sep = "_") %>%
select(-drop)
现在我们就获得了想要的数据:

使用正则表达式来处理
如果这件事情用正则表达式,更加简单,stringr这个包里面的str_match
函数是我的最爱,因为他可以返回括号中的内容,做到精确匹配和返回。
library(stringr)
group <- str_match(data$group,"whole_blood_(.*)_.*")
metadata <- data.frame(GSM=data$GSM,group=group[,2])
解释一下,whole_blood_(.*)_.*
是什么意思。正则表达式,代表的是我们观察世界的模式。举个例子,"whole_blood_control_33",每一个样本名称都是这样的,总结一下就是,
- 先出现
whole_blood_
- 再出现一串字符
control
- 后面跟着下划线
_
- 最后跟这一串字符结束
33
用点好代表任何字符,用*
号代表出现0次或者多次,那么刚才的模式就可以写成whole_blood_.*_.*
。 因为我们需要的是两个下滑线中间的部分,所以给他一个括号,str_match
就会识别并返回。此时模式就写出了这样whole_blood_(.*)_.*
。
结果是一模一样的。

学习字符串stringr
而我学习正则表达式就是从这个最爱的函数str_match
开始的,stringr包中还有好几个函数,不过一直觉得很混乱,函数名字容易混淆,直到遇到了下面的图。

模式用pattern来表示,他把正则表达式在字符串的功能分为四个方面,分别是
- 查找:Detect pattern,确定有没有
- 定位:Locate pattern, 返回起止位置
- 取回:Extract pattern, 返回匹配的条目
- 替换:Replace pattern,我们可以替换匹配的模式,返回替换后的结果
总结一下就是一下几个函数:

我们以此讲一下这几个函数的使用:
创建一个需要练习的字符串
strings <- c(
"apple",
"219 733 8965",
"329-293-8753",
"Work: 579-499-7527; Home: 543.355.3679"
)
再创建一个可以匹配电话号码的模式
# [2-9][0-9]{2} 三个数字,第一个数字不为零
# [- .] -或者.号
# [0-9]{3} 三个数字
# [0-9]{4} 四个数字
pattern <- "([2-9][0-9]{2})[- .]([0-9]{3})[- .]([0-9]{4})"
用str_view函数学习正则表达式
这个函数是用来学习正则表达式的
str_view(strings, pattern)
返回的结果,以图示化展示模式匹配的结果

以下仅仅通过更改函数名称,即可返回不同的结果
1.查找
str_detect
,从strings中检测能否和pattern匹配,返回的是逻辑值,有点像grepl
str_detect(strings, pattern)

结合str_view的结果,表示,2,3,4确实匹配到了结果。
2.定位
str_locate
,从strings中检测能否和pattern匹配,返回匹配的起止位置
str_locate(strings, pattern)

3.取回
这个又分为三个层面,层层递进
第一,str_subset
返回的是匹配到的原始条目
str_subset(strings, pattern)

第二,
str_extract
返回的是匹配到的模式
str_extract(strings, pattern)

第三,
str_match
返回的是数据框第一列是str_extract的数据,后面依次是括号中的内容,模式中有多少个(),就返回多少列。本例中有三对小括号。
str_match(strings, pattern)

4.替换
str_replace
从strings中能够精确匹配pattern的内容,并替换为''XXX-XXX-XXXX''(此处自定义)
str_replace(strings, pattern, "XXX-XXX-XXXX")

stringr这个包中剩下的函数,十分容易理解,可以参考这个帖子自行学习。
https://cran.r-project.org/web/packages/stringr/vignettes/stringr.html
若此,我们就多了一个新技能,最爱str_match
。这时候限制我们的只有看世界的模式了,不过,那是哲学。
网友评论