常用字符处理函数
- nchar: 计算字符串中字符数量或者存储大小, 返回相应值, 与多数函数一样, nchar 是可以接受并返回向量的. 同时, nzchar 可以判断字符串是否非空, 非空返回 TRUE, 空则返回 FALSE.
- substr: 或者 substring 函数, 返回一个字符串的子串,
substr(x, start, end)
, 也可以直接赋值给 substr, 从而能改变 x 的值substring(x, first, last) <- "0"
, 需要注意的是替换字符的数量是相同的. - sub: 替换第一个出现的符合匹配的字符串,
sub(pattern, replacement, x, ignore.case=FALSE, fixed=FALSE)
. - gsub: 替换所有符合匹配的字符串.
- strsplit: 接受一个字符串, 设置 split 根据的字符, 输出一个 list. 需要注意的是 split 是正则表达式, 如果用 "." 等则需要使用正则表达式的方法.
- toupper: 转换为大写字母.
- tolower: 转换为小写字母.
-
paste: 连接字符串, 也可以使用 paste0 函数, 默认不在两个字符串之间加入字符. collapse 参数是设置向量之内的连接字符, 而 sep 是设置向量之间的连接字符.
-
grep: 按照一定 pattern 去查找向量中是否含有该类型字符. 如果有, 默认返回对应的下标, 如果
value = TRUE
, 则直接返回对应的值. 如果没有匹配, 则返回空, 可以使用 any 函数或者 length 函数结果是否为 0 去判断是否有匹配. - print: 把字符输出到终端.
- cat: 连接字符并输出到终端或文件.
正则表达式
R 是支持 POSIX 规范的正则表达式的, 有许多需要比对的函数接受正则表达式, 如 strsplit, grep 等. 需要注意的是, "\" 在正则表达式中是为了把一个保留字符转义为普通字符, 如 "." 把匹配任意字符的 "." 转义为句点, 那么在 R 中, 如果把相应的正则表达式保存在字符串中, 则应该使用两个 "\", 如我要转义正则表达式中匹配任意字符的 "." 为句点, reg.exp <- "\\.txt"
(有的时候可以使用方括号 "[.]txt"
). 如果使用 readline 函数从终端读取, 则只用使用一个 "\", R 解释器可以解读.
保留字符
在 R 中正则表达式有一些保留字符, 这些保留字符在正则表达式中有特殊含义, 如果字符串中有该字符, 需要进行转意. R 使用 POSIX 兼容的正则表达式, 和 linux 终端下的很接近.
. ^ $ + ? * ( ) [ ] { } | \
基本用法
字符与字符集
在正则表达式中, 一个字符或者一个字符集本身只代表一个值. 一个字符代表的就是自身, 而字符集代表的是符合集合的任意一个字符, 更多的字符匹配需要通过指定数量来获得. 下面所列的几个地为是一样的, 如 "a" 的地位和 "[:alpha:]" 的地为一样, 在 "a" 外面需要一个方括号的地方, 如 [a]
, 在 "[:alpha:]" 也需要, 如 [[alpha:]]
- .: 匹配任意一个字符.
- .: 在 R 中或者 "\.", 代表句点, 需要转义.
- a: 代表一个字符 "a", 其他字符类似.
- [:alnum:]: 所有的字母和数字, A-Z, a-z, 0-9, alpha and number.
- [:alpha:]: 所有的字母, A-Z, a-z.
- [:blank:]: space and tab, 空格和制表符.
- [:cntrl:]: 控制字符, 响铃, 退格, 水平制表符, 归位, 转义等.
- [:digit:]: 数字, 0-9.
- [:graph:]: 可视字符, 所有的数字, 字母, 标点等可以看到的字符.
- [:lower:]: 小写字母, a-z.
- [:print:]: 可打印字符, 包括空格和可视字符.
- [:punct:]: 标点,
][!"#$%&'()*+,./:;<=>?@\\^_\
~-`. - [:space:]: 空白符号, 空格制表符等.
- [:upper:]: 大写字母, A-Z.
逻辑与分组
- |: 逻辑或, 代表两者中取一个
- (): 分组, 与 | 一起用, 代表在所包含的模式中符合一个,
(a|b)
. - []: 匹配一个, 匹配其中包含的一个字符或字符集,
[a[:digit:]]
.
数量
数量符号指明其前面的字符重复的数量.
- ?: 前面的字符重复 0 次或 1 次.
- *: 前面的字符重复 0 次或多次.
- +: 前面的字符重复 1 次或多次.
- {n}: 前面的字符重复 n 次.
- {min,}: 前面的字符重复至少 min 次.
- {min, max}: 前面的字符重复 min 次到 max 次.
位置
有的时候需要匹配位置.
- ^: 把位置锚定在行首.
- $: 把位置锚定在行尾.
常见字符串处理问题
取字符串的部分字符
主要使用 strsplit 函数.
丽莎问了一个问题, 想要提取一系列的物种学名中的属名, 这些学名有的有亚种加词, 有的没有.
species <- c("Corvus_corone",
"Cyanopica_cyanus",
"Pica_pica_serica",
"Corvus_macrorhynchos")
genus <- unname(sapply(species, function(m){unlist(strsplit(m,split="_"))[1]}))
上面的代码可以解决这个问题.
- unlist: 把 strsplit 输出的 list 变成向量.
- sapply: 把一个操作用在一个向量上. FUN 可以为 "[" 就可以提取 list 中特定的部分,
sapply(list, "[", 1)
. - unname: sapply 得到的结果有 names, 使用 unname 可以去掉 names.
取字符串中的单个字母
如果需要对字符串中的单个字母进行操作或判断, 则应该先把整个字符串转换为单个字母的向量, 这个任务能通过 substr 来完成.
state <- ’Mississippi’
len <- nchar(state)
ltrs <- substr(state,1:len,1:len)
ltrs
[1] "M" "i" "s" "s" "i" "s" "s" "i" "p" "p" "i"
除去字符串最后一个字符
石强问怎么把一些字符串最后的句号给去掉, 查了网站, 没看到类似 python rstrip 之类的函数, 那就用多个函数组合吧. 需要注意的是英文句号本身是正则表达式里面的符号, 需要用方括号括起来.
some <- c("my.", "name", "is", "Wolfson.")
substr(x = some[grep(pattern = "[.]$", x = some)],
start = c(1,1),
stop = nchar(some[grep(pattern = "[.]$", x = some)]) - 1)
字符和对象的转换, 运行字符串中的命令
有的时候需要把接下来需要运行的命令保存在字符串中, 然后再运行. 这种情况下, 需要 parse, eval, call, get 等函数.
rna.time.conditions <- c(0, 6, 24, 48)
rna.time.names <- vector()
for (i in c(1:4)) {
rna.time.names[i] <- paste("rna.time.",
rna.time.conditions[i],
sep = "")
## setting names.
tmp.load.rna.data <- paste(rna.time.names[i],
" <- ",
"ballgown(dataDir = rna.data.parent.dir, ",
'samplePattern = "*-',
rna.time.conditions[i],
'-*", meas = "all")',
sep = '')
## excute strings
eval(parse(text = tmp.load.rna.data)) # excute
write(x = get(rna.time.names[i]),
file = paste(rna.time.conditions[i], "_data.txt", sep = ''))
## write data to file.
## write the differencial expressed gene list to file.
}
- parse: 把字符串转化为 R 表达式, file 指定输入的文件, 或者使用 text 指定包含所需字符串的对象.
- deparse: 把表达式转换为字符串.
- eval: 运行 R 表达式, 需要先使用 parse 把字符串转化为 R 表达式.
- call: 把字符串转化为函数表达式,
call(FUNCTIONNAME)
. - get: 通过名称来获得数据对象,
get(DATANAME)
. - substitute: 返回 parse tree, 可以和 deparse 配合, 获得函数参数实际的变量名.
我们也许需要一个函数的参数或函数名都按照需求有所变化, 也就是说, 希望能通过函数名调用参数, 而又可以单独去赋予该函数参数, 这个时候就需要 do.call 函数.
sortframe = function(df,...)df[do.call(order,list(...)),] # 对 data.frame 的每一列进行排序.
- do.call, do.call 接受一个函数名和该函数的参数的 list, 并且调用该函数.
-
不匹配其中任何一个. ↩