使用 Stringr 进行数据清理
Data Cleaning Using Stringr
我有一个包含两列的数据 table,第一列包含一个 Id 变量,第二列包含一个字符串。第二列中的字符串格式为
"A:randomString|B:randomString|C:randomString"
.
我想将 table 更改为具有 4 列:Id、A、B 和 C。Id 将保持不变,A 将在每个 A: 之后具有随机字符串,B 将具有每个 B: 之后的字符串,C 将具有 C:.
之后的字符串
是否可以使用 stringr 来做到这一点?
您可以使用 stringr::str_extract()
和利用 lookbehind and lookahead:
的正则表达式来做到这一点
library(tidyverse)
df <- readr::read_csv("~/../Downloads/test1.csv")
df <- df %>%
mutate(A = str_extract(col2, "(?<=A:).*?(?=\|)"),
B = str_extract(col2, "(?<=B:).*?(?=\|)"),
C = str_extract(col2, "(?<=C:).*?$")
)
例子
样本数据df
为:
> df
# A tibble: 2 x 2
Id col2
<int> <chr>
1 1 A:frog's legs|B:popcorn|C:white_wine!
2 2 A:banana SUNDAE|B:!@$%^|C:123456
使用dplyr::mutate()
创建新列A、B和C:
> df <- df %>%
+ mutate(A = str_extract(col2, "(?<=A\:).*?(?=\|)"),
+ B = str_extract(col2, "(?<=B\:).*?(?=\|)"),
+ C = str_extract(col2, "(?<=C\:).*?$")
+ )
此操作后的data.framedf
为:
> df
# A tibble: 2 x 5
Id col2 A B C
<int> <chr> <chr> <chr> <chr>
1 1 A:frog's legs|B:popcorn|C:white_wine! frog's legs popcorn white_wine!
2 2 A:banana SUNDAE|B:!@$%^|C:123456 banana SUNDAE !@#$%^ 123456
正则表达式的工作原理
正则表达式对 A:
(在第一个字符串中)使用 lookbehind,对 |
使用 lookahead 来匹配这两者之间的所有字符。第二个字符串 B:
同上。对于第三个字符串,它匹配 C:
之后的所有字符,直到字符串结尾。
警告
以上假定分隔字符 |
将 不 出现在随机字符串中。如果不是这种情况,则必须稍微调整正则表达式以解决此问题:
> df
# A tibble: 2 x 2
Id col2
<int> <chr>
1 1 A:frog's l|egs|B:popcorn|C:white_wine!
2 2 A:banana SUNDAE|B:!@|$%^|C:123456
注意上面随机字符串中的 |
字符。我们更改正则表达式的前瞻部分以解决这个问题:
> df <- df %>%
+ mutate(A = str_extract(col2, "(?<=A:).*?(?=\|B:)"),
+ B = str_extract(col2, "(?<=B:).*?(?=\|C:)"),
+ C = str_extract(col2, "(?<=C:).*?$")
+ )
> df
# A tibble: 2 x 5
Id col2 A B C
<int> <chr> <chr> <chr> <chr>
1 1 A:frog's l|egs|B:popcorn|C:white_wine! frog's l|egs popcorn white_wine!
2 2 A:banana SUNDAE|B:!@|$%^|C:123456 banana SUNDAE !@|$%^ 123456
您可以选择使用这个:
library(stringr)
xt <- "A:randomString|B:randomString|C:randomString"
colnm <- unlist(str_extract_all(xt, "[A-Z](?=:)"))
values <- setNames(data.frame(rbind(unlist(str_extract_all(xt,"(?![A-Z]:)\w+" )))), colnm)
输出:
print(values)
A B C
1 randomString randomString randomString
我有一个包含两列的数据 table,第一列包含一个 Id 变量,第二列包含一个字符串。第二列中的字符串格式为
"A:randomString|B:randomString|C:randomString"
.
我想将 table 更改为具有 4 列:Id、A、B 和 C。Id 将保持不变,A 将在每个 A: 之后具有随机字符串,B 将具有每个 B: 之后的字符串,C 将具有 C:.
之后的字符串是否可以使用 stringr 来做到这一点?
您可以使用 stringr::str_extract()
和利用 lookbehind and lookahead:
library(tidyverse)
df <- readr::read_csv("~/../Downloads/test1.csv")
df <- df %>%
mutate(A = str_extract(col2, "(?<=A:).*?(?=\|)"),
B = str_extract(col2, "(?<=B:).*?(?=\|)"),
C = str_extract(col2, "(?<=C:).*?$")
)
例子
样本数据df
为:
> df
# A tibble: 2 x 2
Id col2
<int> <chr>
1 1 A:frog's legs|B:popcorn|C:white_wine!
2 2 A:banana SUNDAE|B:!@$%^|C:123456
使用dplyr::mutate()
创建新列A、B和C:
> df <- df %>%
+ mutate(A = str_extract(col2, "(?<=A\:).*?(?=\|)"),
+ B = str_extract(col2, "(?<=B\:).*?(?=\|)"),
+ C = str_extract(col2, "(?<=C\:).*?$")
+ )
此操作后的data.framedf
为:
> df
# A tibble: 2 x 5
Id col2 A B C
<int> <chr> <chr> <chr> <chr>
1 1 A:frog's legs|B:popcorn|C:white_wine! frog's legs popcorn white_wine!
2 2 A:banana SUNDAE|B:!@$%^|C:123456 banana SUNDAE !@#$%^ 123456
正则表达式的工作原理
正则表达式对 A:
(在第一个字符串中)使用 lookbehind,对 |
使用 lookahead 来匹配这两者之间的所有字符。第二个字符串 B:
同上。对于第三个字符串,它匹配 C:
之后的所有字符,直到字符串结尾。
警告
以上假定分隔字符 |
将 不 出现在随机字符串中。如果不是这种情况,则必须稍微调整正则表达式以解决此问题:
> df
# A tibble: 2 x 2
Id col2
<int> <chr>
1 1 A:frog's l|egs|B:popcorn|C:white_wine!
2 2 A:banana SUNDAE|B:!@|$%^|C:123456
注意上面随机字符串中的 |
字符。我们更改正则表达式的前瞻部分以解决这个问题:
> df <- df %>%
+ mutate(A = str_extract(col2, "(?<=A:).*?(?=\|B:)"),
+ B = str_extract(col2, "(?<=B:).*?(?=\|C:)"),
+ C = str_extract(col2, "(?<=C:).*?$")
+ )
> df
# A tibble: 2 x 5
Id col2 A B C
<int> <chr> <chr> <chr> <chr>
1 1 A:frog's l|egs|B:popcorn|C:white_wine! frog's l|egs popcorn white_wine!
2 2 A:banana SUNDAE|B:!@|$%^|C:123456 banana SUNDAE !@|$%^ 123456
您可以选择使用这个:
library(stringr)
xt <- "A:randomString|B:randomString|C:randomString"
colnm <- unlist(str_extract_all(xt, "[A-Z](?=:)"))
values <- setNames(data.frame(rbind(unlist(str_extract_all(xt,"(?![A-Z]:)\w+" )))), colnm)
输出:
print(values)
A B C
1 randomString randomString randomString