Code
library(stringr)
library(tidyverse)
Rui
November 8, 2022
参考 Hadley Wickham 的 R for Data Science (R数据科学)。开源版本:https://r4ds.had.co.nz/
可以使用双引号(英文)来创建字符串:
在 base R
中:
在 stringr
中:
为什么返回的是 1?因为 length()
函数求的是向量的长度,它把 string1
当作是只包含一个元素的字符串向量,所以返回的结果是 1。
base R
中使用 nchar()
求字符串的长度,注意空格也是一个字符串。
也可以使用 stringr
中的 str_length()
:
base R
中使用 paste()
和 paste0()
函数。
stringr
中使用 str_c()
函数:
可以使用 sep
参数指定拼接时的分隔符:
而且 str_c()
是向量化的函数,它可以对长度较短的向量循环补齐以匹配较长的向量:
必须对缺失值保持警觉,和很多其他函数一样,缺失值 NA 是可传染的。如果想让它直接输出为 “NA” ,可以使用 str_replace_na()
:
长度为 0 的字符串将会被悄无声息地丢弃。但要注意的是:虽然长度为 0 的字符串会被丢弃,但与其相连的分隔符却会被保留。
若要将字符串向量中的所有元素合并地话,可以使用 collapse()
参数。但特别要注意 sep
与 collapse
联用的情况:
从上面这个例子来看:sep
的优先度比 collapse
要高。
base R
中的 substr()
函数可以使用我们指定的起点和终点对字符串取子集:
或者使用 stringr
中的 str_sub()
函数:
如果 end
参数比 start
参数小,则返回一个空字符串:
str_sub()
同样也是一个向量化的函数:
其中的 end
和 start
参数还可以接受负数,表示从后往前索引:
利用该函数还可以实现就地改值:
当字符串非常长时,可以使用 str_wrap()
函数自动换行(它的功能不止如此,主要是让字符串的输出更加整洁):
str_trim()
函数可以去除字符串头、尾部的空白:
可以指定移除字符串头部还是尾部还是首尾两端的空白:
下一节中,将会介绍处理字符串的利器——正则表达式。内容主要包括:正则表达式基础、使用正则表达式进行模式匹配、stringr
中相关的函数。
---
title: "使用 stringr 处理字符串(一)"
author: "Rui"
date: "2022-11-8"
categories: [R, 数据处理, stringr]
image: "ocean.jpg"
format:
html:
code-fold: true
code-tools: true
---
```{r setup, include = FALSE}
# 设置默认参数
knitr::opts_chunk$set(
echo = TRUE,
fig.align = "center",
message = FALSE,
warning = FALSE,
collapse = TRUE
)
```
![](ocean.jpg)
> 参考 Hadley Wickham 的 *R for Data Science* (R数据科学)。开源版本:<https://r4ds.had.co.nz/>
::: {.callout-tip}
虽然不少处理字符串的工作使用 `base R` 中的函数就可以完成,但我更推荐使用 `stringr` 中的函数。一方面可以使你的代码更加 tidy,另一方面:`stringr` 中的函数都有共同的前缀 "str_",在你不太记得函数的具体名称时只要在 `RStudio` 中输入函数前缀 "str_",`RStudio` 就可以为你自动补齐。
:::
```{r}
library(stringr)
library(tidyverse)
```
::: {.callout-note}
虽然 `stringr` 是 `tidyverse` 生态中的一员,但它并不是 `tidyverse` 的核心包,所以需要手动加载 `stringr` 。
:::
## 字符串基础
### 字符串的创建
可以使用双引号(英文)来创建字符串:
```{r}
string1 <- "I Love R"
print(string1)
```
### 英文字母大小写转换
在 `base R` 中:
```{r}
toupper(string1)
tolower(string1)
```
在 `stringr` 中:
```{r}
str_to_upper(string1)
str_to_lower(string1)
```
### 字符串长度
```{r}
length(string1)
```
为什么返回的是 1?因为 `length()` 函数求的是向量的长度,它把 `string1` 当作是只包含一个元素的字符串向量,所以返回的结果是 1。
`base R` 中使用 `nchar()` 求字符串的长度,注意空格也是一个字符串。
```{r}
nchar(string1)
```
也可以使用 `stringr` 中的 `str_length()`:
```{r}
str_length(string1)
```
### 字符串拼接
`base R` 中使用 `paste()` 和 `paste0()` 函数。
`stringr` 中使用 `str_c()` 函数:
```{r}
str_c("x", "y")
str_c("x", "y", "z")
```
可以使用 `sep` 参数指定拼接时的分隔符:
```{r}
str_c("x", "y", sep = "-")
```
而且 `str_c()` 是向量化的函数,它可以对长度较短的向量循环补齐以匹配较长的向量:
```{r}
str_c(c("I", "You", "We"), "Love", "R", sep = " ")
```
必须对缺失值保持警觉,和很多其他函数一样,缺失值 NA 是可传染的。如果想让它直接输出为 "NA" ,可以使用 `str_replace_na()`:
```{r}
x <- c("x", NA)
str_c(x, "y", sep = "-")
str_c(str_replace_na(x), "y", sep = "-")
```
长度为 0 的字符串将会被悄无声息地丢弃。但要注意的是:虽然长度为 0 的字符串会被丢弃,但与其相连的分隔符却会被保留。
```{r}
str_c("I", "Love", "", sep = " ")
```
若要将字符串向量中的所有元素合并地话,可以使用 `collapse()` 参数。但特别要注意 `sep` 与 `collapse` 联用的情况:
```{r}
str_c(c("I", "Love", "R"), collapse = "-")
str_c(c("I", "You"), "Love R", sep = " ", collapse = " and ")
```
从上面这个例子来看:`sep` 的优先度比 `collapse` 要高。
### 字符串索引(取子集)
`base R` 中的 `substr()` 函数可以使用我们指定的起点和终点对字符串取子集:
```{r}
substr(string1, start = 1, stop = 5)
substr(string1, 1, 5) # 简写
```
或者使用 `stringr` 中的 `str_sub()` 函数:
```{r}
str_sub(string1, start = 1, end = 5)
str_sub(string1, 1, 5) # 简写
```
如果 `end` 参数比 `start` 参数小,则返回一个空字符串:
```{r}
str_sub(string1, 5, 1)
```
`str_sub()` 同样也是一个向量化的函数:
```{r}
x <- c("Apple", "Banana", "Pear")
str_sub(x, 1, 3)
```
其中的 `end` 和 `start` 参数还可以接受负数,表示从后往前索引:
```{r}
str_sub(x, -3, -1)
```
利用该函数还可以实现就地改值:
```{r}
str_sub(x, 1, 1) <- str_to_lower(str_sub(x, 1, 1))
x
```
## 其他一些函数
当字符串非常长时,可以使用 `str_wrap()` 函数自动换行(它的功能不止如此,主要是让字符串的输出更加整洁):
```{r}
x <- "我在朦胧中,眼前展开一片海边碧绿的沙地来,上面深蓝的天空中挂着一轮金黄的圆月。我想:希望是本无所谓有,无所谓无的。这正如地上的路;其实地上本没有路,走的人多了,也便成了路。"
cat(str_wrap(x, width = 40))
```
`str_trim()` 函数可以去除字符串头、尾部的空白:
```{r}
x <- " I love R "
str_trim(x)
```
可以指定移除字符串头部还是尾部还是首尾两端的空白:
```{r}
str_trim(x, side = "left")
str_trim(x, side = "both")
```
## 下一节
下一节中,将会介绍处理字符串的利器——正则表达式。内容主要包括:正则表达式基础、使用正则表达式进行模式匹配、`stringr` 中相关的函数。