使用Stringr清理数据

时间:2017-10-23 02:45:18

标签: r stringr

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

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

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

之后的字符串

是否可以使用stringr执行此操作?

2 个答案:

答案 0 :(得分:1)

您可以使用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.frame df为:

> 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

正则表达式如何工作

正则表达式使用lookbehind用于A:(在第一个字符串中)和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

答案 1 :(得分:1)

您可以选择使用它:

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