R数据清洗系列之学会使用stringr处理字符串(一)
大家好,我是阿琛。以简单易懂的介绍,带领大家快速入门数据处理,这里是R数据清洗栏目。在前两期的内容中(十分钟轻松学会R数据清洗技巧,生信小白必须跨越的第一关R语言小白入门课|一刻钟带你学会R数据转化),我们基于tidyverse包的核心包dplyr包,分别介绍了filter(),arrange(),select(),mutate(),以及summarize()5大函数的功能与使用方法。
然而,在日常的分析过程中,除了对数据进行操作,还有一种十分重要的变量类型,即字符串。不管是基于病人id编号的筛选,还是识别变量名中某一特定字符,都要求我们掌握相应的处理手段。因此,对字符串的处理方法,是一个必备的重要技能。
尽管R语言的基础包中也包含了许多字符串处理函数,但是由于不同函数之间使用方法差别较大,且函数名复杂,因此不做重点推荐。在此,我们主要讲解tidyverse包中的另一个包,stringr包。同时,尽管字符串中往往通常包含半结构化或者非结构化的内容,但我们往往可以使用简练的语言来描述字符串中的通用模式,这也就是我们常说的一个重要的概念,即正则表达式(regular expression,regexp)
下面,我们一起来看一下字符串的处理基础知识。
1.R包的安装与读取
if(!require(tidyverse))install.packages("tidyverse")if(!require(stringr))install.packages("stringr")library(tidyverse)library(stringr)
由于stringr包不会一直处理文本数据,所以stringr包不属于tidyverse包的核心包。因此,在需要使用时我们可以通过命令来加载它。
2.字符串的生成
str1 <- "Proportion of SCNA fibroblasts in tumor is much higher than that in normal tissue."str1#[1] "Proportion of SCNA fibroblasts in tumor is much higher than that in normal tissue."
首先,我们可以使用单引号或者双引号来快速创建字符串。在这里,需要注意的,尽管在R语言中单引号和双引号之间没有明确的区别,但是一般而言,还是推荐使用“ ”来创建。
str2 <- c("abcde", "defxy", "xyzab")str2#[1] "abcde""defxy""xyzab"
其次,与向量中的使用方法一致,同样可以通过c()函数来创建包含多个字符串的字符向量。
dat <- read.table("string_data.txt", sep = "\t",header = T)str(dat)
当然,在分析过程中,我们最常用的是直接通过read.table()函数将外部数据读取进来。使用str()函数快速查看其中的数据结构类型,可以看到数据集dat中包含了7个字符型(character)的变量。
接着,我们将逐个讲解一些常用的函数使用方法。
3.stringr包的相关函数简介
3.1 字符串长度str_length()函数
首先介绍的是str_length()函数。顾名思义,该函数的作用是检测字符串的长度。
str_length(str1)#[1] 82
结果显示,变量str1中包含82个字符。注意,在R语言中,引号内的便是一个字符串,因此在统计长度时,空格和句号都会被算成一个字符长度。
另外,stringr包中的str_xxx()函数往往是向量化的,可以自动循环短向量,分别进行计算或处理。
str_length(str2)#[1] 3 3 3
3.2 字符串组合str_c()函数
除了检测长度,我们也可以使用str_c()将两个或者多个字符串进行组合;不添加其他参数设置时,函数默认直接连接。
str_c("abcde", "defxy", "xyzab")#[1] "abcdedefxyxyzab"
当然,我们也可以通过对参数sep进行设置,调整字符串之间的连接形式。比如,sep = ","表示不同字符串在组合时使用逗号(,)来进行间隔。
str_c("abcde", "defxy", "xyzab", sep = ",")#[1] "abcde,defxy,xyzab"
str_c函数同样具有自动循环短向量的功能,而不需要另外设置循环语句,或者另外学习paste0()函数的使用方法。
str_c("abc", c("d", "e", "f"), "xyz")#[1] "abcdxyz""abcexyz""abcfxyz"
此外,str_c()函数还可以与if判断语句进行联合使用。
str_c("This sample ", dat[1,]," ", "is ",if(str_sub(dat[1,], 14, 16) == "11A")"normal",".")#[1] "This sample TCGA-CG-5734-11A-01R-1602-13 is normal."
通过判断,可以得到str_sub(dat[1,], 14, 16) == "11A"的结果为TRUE;因此,最终得到的输出结果为"This sample TCGA-CG-5734-11A-01R-1602-13 is normal."。关于这句代码的讲解,我们先留个小悬念,待学习了下一个str_sub函数的使用方法以后再来解释。
3.3 字符串取子集str_sub()函数
向量和数据框等可以取子集进行操作,那么字符串作为一个变量来讲,同样可以进行取子集操作。
使用str_sub()函数取子集操作,以提取字符串的一部分,除了提供字符串参数外,需要同时提供start和end参数,表示子字符串的起始和终止位置。
str_sub(str2, 1, 3)#[1] "abc""def""xyz"
在该过程中,提取变量str2中每个字符串第1个到第3个到字符组成一个新的字符串向量。
再回过头去看上面的代码,dat[1,]为TCGA-CG-5734-11A-01R-1602-13,通过strsub()函数提取第14到16位的字符,得到结果“11A”;因此,通过判断语句“==”,得出`strsub(dat[1,], 14, 16) == "11A"`的结果为TRUE,执行后面的输出结果“normal”。
进一步加大难度,我们可以对dat中每个样本id进行分组判断。
dat$group <- ifelse(str_sub(dat[,1], 14, 16) == "11A", "normal","tumor")
通过将str_sub()函数与ifelse()函数相互结合,设置分组;如果id的第14到16位为11A,则表示该样品为normal样品,否则为tumor样品。
3.4 其他常用的相关函数类型
(1). 字符串拆分:str_split()函数
(2). 字符串排序:str_sort()函数
(3). 字符检测:str_detect()函数
(4). 字符串计数:str_count()函数
(5). 字符串替换:strreplace()/strreplace_all()函数
(6). 提取匹配到的:str_subset()函数
其中,关于str_detect()函数的使用,其最终返回的结果是一个逻辑判断变量,在使用过程中需要注意。
好啦,本次的分享内容就到此为止了。在最后提到的这些常用函数,大家可以先自行尝试使用。在下次的内容中,我们将进一步讲解这些函数的方法,以及正则表达式的使用。
通过回复“阿琛31”得到本次的示例讲解代码~
欢迎大家关注解螺旋生信频道-挑圈联靠公号~
继续阅读
阅读原文