首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Stringr进行数据清理

使用Stringr进行数据清理
EN

Stack Overflow用户
提问于 2017-10-23 02:45:18
回答 2查看 371关注 0票数 0

我有一个包含两个列的数据表,第一个列包含一个Id变量,第二个列包含一个字符串。第二列中的字符串为格式。

"A:randomString|B:randomString|C:randomString"

我想将表修改为4列: Id、A、B和C。Id保持不变,A在每个A:后面有随机字符串,B在每个B:后面有字符串,C在C:后面有字符串。

是否可以使用stringr来完成这个任务?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-09 13:05:47

您可以使用stringr::str_extract()和使用回顾和展望的正则表达式来完成这一任务。

代码语言:javascript
复制
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是:

代码语言:javascript
复制
> 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:

代码语言:javascript
复制
> df <- df %>%
+   mutate(A = str_extract(col2, "(?<=A\\:).*?(?=\\|)"),
+          B = str_extract(col2, "(?<=B\\:).*?(?=\\|)"),
+          C = str_extract(col2, "(?<=C\\:).*?$")
+   )

此操作后的data.frame df是:

代码语言:javascript
复制
> 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: (在第一个字符串中)和查找|来匹配这两个字符串之间的所有字符。第二个字符串B:也是如此。对于第三个字符串,它匹配C:后面的所有字符,直到字符串结束。

警告

以上假设分隔字符|而不是在随机字符串中。如果不是这样,则必须稍微调整正则表达式,以考虑到这一点:

代码语言:javascript
复制
> 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

注意上面随机字符串中的|字符。我们更改正则表达式的前瞻性部分,以说明这一点:

代码语言:javascript
复制
> 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
票数 1
EN

Stack Overflow用户

发布于 2017-12-09 14:05:27

您可以选择使用以下内容:

代码语言:javascript
复制
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)

输出

代码语言:javascript
复制
print(values)
             A            B            C
1 randomString randomString randomString
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46881250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档