![]() |
唠叨的猴子 · PHP简单实现图片格式转换(jpg转png, ...· 6 月前 · |
![]() |
想旅行的烈马 · JAVA学习中Swing部分JDialog对 ...· 10 月前 · |
![]() |
睡不着的针织衫 · tf.keras.callbacks.mod ...· 11 月前 · |
![]() |
潇洒的紫菜汤 · URL.createObjectURL讲解_ ...· 1 年前 · |
cppFunction()
转换简单的C++函数—Fibnacci例子
sourceCpp()
转换C++程序—正负交替迭代例子
sourceCpp()
转换C++源文件中的程序—正负交替迭代例子
sourceCpp()
转换C++源程序文件—卷积例子
wrap()
把C++变量返回到R中
as()
函数把R变量转换为C++类型
as()
和
wrap()
的隐含调用
clone
函数
kable()
函数制作表格
s <- c("123", "abc", "张三李四", "@#$%^&")
## [1] "123" "abc" "张三李四" "@#$%^&"
R中处理文本型数据的函数有文件访问函数以及readLines
,nchar
,
paste
,sprintf
, format
,formatC
, substring
等函数。
R支持正则表达式, 函数grep
, grepl
, sub
, gsub
, regexpr
,
gregexpr
, strsplit
与正则表达式有关。
字符型函数一般都是向量化的,
对输入的一个字符型向量的每个元素操作。
R扩展包stringr和stringi提供了更方便、功能更强的字符串功能,
包括正则表达式功能。
其中stringr是常用功能,
stringi是更基本、更灵活的功能,
一般使用stringr就足够了。
stringr包的函数名大多都以str_
开头。
下面先介绍常用的较简单的字符串函数,
包括stringr包的函数与基本R函数。
40.3 字符串连接、重复
stringr::str_c()
用来把多个输入自变量按照元素对应组合为一个字符型向量,
用sep
指定分隔符,默认为不分隔。
类似于R中向量间运算的一般规则,
各自变量长度不同时短的自动循环使用。
非字符串类型自动转换为字符型。
## [1] "x*a" "y*b"
## [1] "data1.txt" "data2.txt" "data3.txt"
字符型缺失值参与连接时,
结果变成缺失值;
可以用str_replace_na()
函数将待连接的字符型向量中的缺失值转换成字符串"NA"
再连接。
用collapse
选项要求将连接后的字符型向量的所有元素连接在一起,
collapse
的值为将多个元素合并时的分隔符。
## [1] "a---bc---def"
在使用了collapse
时如果有多个要连接的部分,
str_c()
函数先将各部分连接成为一个字符型向量,
然后再把结果的各个向量元素连接起来。
## [1] "data1.txt;data2.txt;data3.txt"
stringr::str_flatten()
类似于stringr::str_c()
仅有collapse
参数作用一样,
仅将一个字符型向量的各个元素按照collapse
参数指定的分隔符连接成一个长字符串,
collapse
默认值是空字符串,如:
## [1] "a---bc---def"
## [1] "abcdef"
基本R的paste()
函数与stringr::str_c()
函数有类似的用法,
但是参数sep
的默认值是空格。
基本R的paste0()
函数相当于stringr::str_c()
函数固定sep
参数为空字符串。
## [1] "x*a" "y*b"
## [1] "data1.txt" "data2.txt" "data3.txt"
## [1] "data1.txt" "data2.txt" "data3.txt"
## [1] "a---bc---def"
## [1] "data1.txt;data2.txt;data3.txt"
stringr::str_dup(string, times)
类似于rep()
函数,
可以将字符型向量的元素按照times
指定的次数在同一字符串内重复,如:
## [1] "abcabcabc" "长江长江长江"
也可以针对每个元素指定不同重复次数,如
## [1] "abcabcabc" "长江长江"
40.4 格式化输出
40.4.1 format()
函数
format()
函数可以将一个数值型向量的各个元素按照统一格式转换为字符型,
## [1] "1"
## [1] "1.2"
## [1] "1.23"
## [1] "1.00" "1.20" "1.23"
选项digits
与nsmall
共同控制输出的精度,
nsmall
控制非科学记数法显示时小数点后的至少要有的位数,
digits
控制至少要有的有效位数。
这使得输出的宽度是不可控的,
## [1] " 3.1415927" "31415.9265359"
width
参数指定至少要有的输出宽度,
不足时默认在左侧用空格填充,如:
## [1] " 1.00"
format()
还有许多选项,
详见函数的帮助。
40.4.2 sprintf()
函数
format()
函数无法精确控制输出长度和格式。
sprintf
是C语言中sprintf
的向量化版本,
可以把一个元素或一个向量的各个元素按照C语言输出格式转换为字符型向量。
第一个自变量是C语言格式的输出格式字符串,
其中%d
表示输出整数,%f
表示输出实数,
%02d
表示输出宽度为2、不够左填0的整数,
%6.2f
表示输出宽度为6、宽度不足时左填空格、含两位小数的实数,
比如,标量转换
## [1] " 3.14"
又如,向量转换:
## [1] "tour001.jpg" "tour005.jpg" "tour010.jpg" "tour015.jpg" "tour100.jpg"
还可以支持多个向量同时转换,如:
## [1] "1x5= 5" "2x4= 8" "3x3= 9" "4x2= 8" "5x1= 5"
40.4.3 字符串插值函数
许多脚本型程序设计语言都有在字符串的内容中插入变量值的功能,
R本身不具有这样的功能,
sprintf()
函数有类似作用但只是一个不方便使用的副作用。
stringr::str_glue()
和stringr::str_glue_data()
提供了字符串插值的功能。
只要在字符串内用大括号写变量名,
则函数可以将字符串内容中的变量名替换成变量值,如:
## 姓名: 李明
## 电话号码: 13512345678
上面的例子直接用了换行符"\n"
来分开不同内容。
也可以输入多个字符串作为自变量,
内容自动连接在一起,可以用参数.sep
指定分隔符:
## 姓名: 李明, 电话号码: 13512345678
## 姓名: 李明; 电话号码: 13512345678
也可以直接在str_glue()
中指定变量值,如:
## 姓名: 张三; 电话号码: 13588888888
stringr::str_glue_data()
则以一个包含变量定义的对象.x
为第一自变量,
类型可以是环境、列表、数据框等。如:
## 姓名: 王五; 电话号码: 13500000000
需要插入原样的大括号时,
可以双写,如:"{{...}}"
。
40.5 字符串长度
stringr::str_length(string)
求字符型向量string
每个元素的长度。
一个汉字长度为1。
## [1] 1 2 3 2
函数nchar(text)
计算字符串长度,默认按照字符个数计算而不是按字节数计算,
## [1] 1 2 3 2
注意函数对输入的字符型向量每个元素计算长度。
nchar()
加选项type="bytes"
可用按字符串占用的字节数计算,
这时一个汉字占用多个字节(具体占用多少与编码有关)。
## [1] 1 2 3 6
40.6 取子串
stringr::str_sub(string, start, end)
字符串字串,
用开始字符位置start
和结束字符位置end
设定字串位置。
用负数表示倒数位置。
默认开始位置为1,
默认结束位置为最后一个字符。
## [1] "2017"
## [1] "2017" "2018"
## [1] "2017"
## [1] "2017"
## [1] "term"
取子串时,一般按照字符个数计算位置,如
## [1] "海淀区"
当起始位置超过总长度或结束位置超过第一个字符时返回空字符串;
当起始位置超过结束位置是返回空字符串。
## [1] ""
## [1] ""
## [1] ""
可以对str_sub()
结果赋值,表示修改子串内容,如:
s <- "term2017"
str_sub(s, 5, 8) <- "18"
## [1] "term18"
字符串替换一般还是应该使用专用的替换函数如stringr::str_replace_all()
,
gsub()
。
基本R的substring(text, first, last)
函数与stringr::str_sub()
功能相同,
但first
和last
参数不允许用负数,
last
的默认值是一个很大的数,所以省略last
时会取到字符串末尾。
substring()
对三个参数text
, first
, last
都是向量化的,
长度不一致时按照一般的不等长向量间运算规则处理。如:
## [1] "term" "2018"
## [1] "term" "2017"
substring()
也允许修改某个字符串的指定子串的内容,如
s <- "123456789"
substring(s, 3, 5) <- "abc"
## [1] "12abc6789"
R的substr(x, start, stop)
作用类似,
但是仅支持x
为字符型向量,
start
和stop
是标量。
40.7 字符串变换
40.7.1 大小写
stringr::str_to_upper(string)
将字符型向量string
中的英文字母都转换为大写。
类似函数有stringr::str_to_lower(string)
转换为小写,
stringr::str_to_title(string)
转换为标题需要的大小写,
stringr::str_to_scentence(string)
转换为句子需要的大小写。
这都是针对英文的,
选项locale
用来选语言,locale="en"
为默认值。
基本R的toupper()
将字符型向量的每个元素中的小写字母转换为大写,
tolower()
转小写。
40.7.2 字符变换表
基本R的chartr(old, new, x)
函数指定一个字符对应关系,
旧字符在old
中,新字符在new
中,x
是一个要进行替换的字符型向量。
比如,下面的例子把所有!
替换成.
,把所有;
替换成,
:
## [1] "Hi, boy." "How do you do."
## [1] "昌平区,大兴区;固安区."
第二个例子中被替换的标点是中文标点,替换成了相应的英文标点。
40.7.3 空白处理
stringr::str_trim(string, side)
返回删去字符型向量string
每个元素的首尾空格的结果,
可以用side
指定删除首尾空格("both"
)、开头空格("left"
)、末尾空格("right"
)。
## [1] "李明" "李明" "李明" "李 明"
## [1] "李明" "李明 " "李明 " "李 明"
## [1] " 李明" "李明" " 李明" "李 明"
stringr::str_squish(string)
对字符型向量string
每个元素,
删去首尾空格,将重复空格变成单个,返回变换后的结果。如:
## [1] "李明" "李明" "李明" "李 明"
基本R函数trimws(x, which)
与str_trim()
作用类似,
选项which="left"
可以仅删去开头的空格,
选项which="right"
可以仅删去结尾的空格。
## [1] "李明" "李明" "李明" "李 明"
## [1] "李明" "李明 " "李明 " "李 明"
## [1] " 李明" "李明" " 李明" "李 明"
为了去掉输入字符串中所有空格,可以用gsub()
替换功能,如:
## [1] "李明" "李明" "李明" "李明"
stringr::str_pad(string, width)
可以将字符型向量string
的每个元素加长到width
个字符,
不足时左补空格,已经达到或超过width
的则不变,如:
## [1] " 12" "1234"
可以用选项side
选择在哪里填补空格,
默认为"left"
,
还可选"right"
,"both"
。
40.7.4 截短或分行
stringr::str_trunc(x, width)
可以截短字符串。
stringr::str_wrap(x, width)
可以将作为字符型向量的长字符串拆分成近似等长的行,
行之间用换行符分隔。
40.7.5 排序
基本R函数sort()
可以用来对字符型向量的各个元素按照字典序排序,
但是字符的先后顺序是按照操作系统的当前编码值次序,
见关于locales
的帮助。
str_sort(x)
对字符型向量x
排序。
可以用locale
选项指定所依据的locale,
不同的locale下次序不同。
默认为"en"
即英语,
中国大陆的GB编码(包括GBK和GB18030)对应的locale是"zh"
。
str_order(x)
返回将x
的各个元素从小到大排序的下标序列。
40.8 简单匹配与查找
40.8.1 开头和结尾匹配
基本R的startsWith(x, prefix)
可以判断字符型向量x
的每个元素是否以prefix
开头,
结果为一个与x
长度相同的逻辑型向量。如
## [1] FALSE TRUE
endsWith(x, suffix)
可以判断字符型向量x
的每个元素是否以suffix
结尾,
## [1] TRUE FALSE
stringr包的str_starts(string, pattern)
判断string
的每个元素是否以模式pattern
开头,
加选项negate=TRUE
表示输出反面结果。
pattern
是正则表达式,
如果需要用非正则表达式,可以用fixed()
或者coll()
保护,如:
## [1] FALSE TRUE
## [1] FALSE TRUE
stringr包的str_ends(string, pattern)
判断是否以给定模式结尾。
40.8.2 中间匹配
函数grep()
, grepl()
等可以用于查找子字符串,
位置不限于开头和结尾,
详见§41.1。
在grepl()
函数中加fixed=TRUE
选项表示查找一般文本内容(非正则表达式)。
比如,查找字符串中是否含有our:
## [1] FALSE TRUE
40.9 字符串替换
stringr包的str_replace_all(string, fixed(pattern), replacement)
在字符型向量string
的每个元素中查找子串pattern
,
并将所有匹配按照replacement
进行替换。
## [1] "New **me" "Old times" "In ** present **me"
用gsub(pattern, replacement, x, fixed=TRUE)
把字符型向量x
中每个元素中出现的子串
pattern
都替换为replacement
(注意与str_replace_all
的自变量次序区别)。
## [1] "New **me" "Old times" "In ** present **me"
设有些应用程序的输入要求使用逗号“,
”分隔,
但是用户可能输入了中文逗号“,”,
就可以用gsub()
来替换:
## [1] "15.34,14.11" "13.25,16.92"
例子中x
的第二个元素中的逗号是中文逗号。
函数sub()
与gsub()
类似,但是仅替换第一次出现的pattern
。
40.10 字符串拆分
stringr::str_split(string, pattern)
对字符型向量string
的每一个元素按分隔符pattern
进行拆分,
每个元素拆分为一个字符型向量,结果是一个列表,列表元素为字符型向量。
其中pattern
是正则表达式,
为了按照固定模式拆分,用fixed()
进行保护。如
x <- c("11,12", "21,22,23", "31,32,33,34")
res1 <- str_split(x, fixed(","))
## [[1]]
## [1] "11" "12"
## [[2]]
## [1] "21" "22" "23"
## [[3]]
## [1] "31" "32" "33" "34"
str_split()
可以用选项n
指定仅拆分出成几项,最后一项合并不拆分,如:
x <- c("11,12", "21,22,23", "31,32,33,34")
res2 <- str_split(x, fixed(","), n=2)
## [[1]]
## [1] "11" "12"
## [[2]]
## [1] "21" "22,23"
## [[3]]
## [1] "31" "32,33,34"
拆分的结果可以用lapply()
, sapply()
,vapply()
等函数处理。
将每个元素的拆分结果转换成数值型:
## [[1]]
## [1] 11 12
## [[2]]
## [1] 21 22 23
## [[3]]
## [1] 31 32 33 34
可以用unlist()
函数将列表中的各个向量连接成一个长向量,如:
## [1] "11" "12" "21" "22" "23" "31" "32" "33" "34"
注意,即使输入只有一个字符串,str_split()
的结果也是列表,
所以输入只有一个字符串时我们应该取出结果列表的第一个元素,如
## [1] "31" "32" "33" "34"
如果确知每个字符串拆分出来的字符串个数都相同,
可以用stringr::str_split_fixed()
,
用参数n
指定拆出来的项数,
这时结果为一个字符型矩阵,
原来的每个元素变成结果中的一行:
x <- c("11,12", "21,22", "31,32")
res3 <- str_split_fixed(x, fixed(","), n=2)
## [,1] [,2]
## [1,] "11" "12"
## [2,] "21" "22"
## [3,] "31" "32"
基本R的strsplit(x,split,fixed=TRUE)
可以把字符型向量x
的每一个元素按分隔符split
拆分为一个字符型向量,
strsplit
的结果为一个列表,
每个列表元素对应于x
的每个元素。
x <- c("11,12", "21,22,23", "31,32,33,34")
res4 <- strsplit(x, split=",", fixed=TRUE)
## [[1]]
## [1] "11" "12"
## [[2]]
## [1] "21" "22" "23"
## [[3]]
## [1] "31" "32" "33" "34"
40.11 文本文件读写
文本文件是内容为普通文字、用换行分隔成多行的文件,
与二进制文件有区别,
二进制文件中换行符没有特殊含义,
而且二进制文件的内容往往也不是文字内容。
二进制文件的代表有图片、声音,
以及各种专用软件的的私有格式文件,
如Word文件、Excel文件。
对于文本文件,可以用readLines()
函数将其各行的内容读入为一个字符型数组,
字符型数组的每一个元素对应于文件中的一行,
读入的字符型数组元素不包含分隔行用的换行符。
最简单的用法是读入一个本地的文本文件,
一次性读入所有内容,用如
其中filename.ext
是文件名,
也可以用全路径名或相对路径名。
当文本文件很大的时候,
整体读入有时存不下,
即使能存下处理速度也很慢,
可以一次读入部分行,逐批读入并且逐批处理,这样程序效率更高。
这样的程序要复杂一些,例如
infcon <- file("filename.ext", open="rt")
batch <- 1000
repeat{
lines <- readLines(infcon, n=batch)
if(length(lines)==0) break
## 处理读入的这些行
close(infcon)
以上程序先打开一个文件,inffcon
是打开的文件的读写入口(称为一个“连接对象”)。
每次读入指定的行并处理读入的行,直到读入了0行为止,
最后关闭infcon
连接。
对文本文件的典型处理是读入后作一些修改,
另外保存。
函数writeLines(lines, con="outfilename.txt")
可以将字符型向量lines
的各个元素变成输出文件的各行保存起来,
自动添加分隔行的换行符。
如果是分批读入分批处理的,
则写入也需要分批写入,
以上的分批处理程序变成:
infcon <- file("filename.ext", open="rt")
outfcon <- file("outfilename.txt", open="wt")
batch <- 1000
while(TRUE){
lines <- readLines(infcon, n=batch)
if(length(lines)==0) break
## 处理读入的这些行, 变换成outlines
writeLines(outlines, con=outfcon)
close(outfcon)
close(infcon)
readLines()
也可以直接读取网站的网页文件,
lines <- readLines(url("https://www.r-project.org/"))
length(lines)
## [1] 116
head(lines)
## [1] "<!DOCTYPE html>"
## [2] "<html lang=\"en\">"
## [3] " <head>"
## [4] " <meta charset=\"utf-8\">"
## [5] " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"
## [6] " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
readr包的read_lines()
和write_lines()
函数起到与基本R中
readLines()
和writeLines()
类似的作用,
read_file()
和read_file_raw()
可以将整个文件读入为一个字符串。