在 R 中使用正则表达式进行字符串拆分和截断

String Splitting and Truncating using Regular Expressions in R

我正在寻求帮助,在 R 中实现一个函数以在 R 中截断我的数据帧的 level_stream 字符串向量,但运气不佳。本质上,当 pre_quiz_score 列中的一行不是 NA 时,我想截断字符串的开头部分直到(并包括)第一个 | 字符,我想截断如果该行的 post_quiz_score 不是 NA,则所有超过最后一个 | 字符的内容。

df <- data.frame(ls = c('123 L0=38/42|425 L0=40/42', NA, '482 L7=7/12|789 L8=5/6|523 L9=2/6'), 
                 pre_quiz_score = c(88, NA, 12), 
                 post_quiz_score = c(NA, NA, 90))

我想以 "tidyverse" 的方式实现它并对其进行矢量化以获得类似

的东西
----------------------------------------------------------------------------
|                 ls                  | pre_quiz_score | post_quiz_score   |
| 425 L0=40/42                        | 88             | NA                |
| NA                                  | NA             | NA                |
| 789 L8=5/6                          | 12             | 90                |

到目前为止,我还没有让 stringr::str_splitgsubsub 正常工作,主要是因为我最终只删除了 |或除最后一个 | 和之后的所有字符串。

我希望这是有道理的,谢谢!

按照您所说的执行逻辑即可:

library(stringi)
library(dplyr)

df <- data.frame(ls = c('123 L0=38/42|425 L0=40/42', NA, '482 L7=7/12|789 L8=5/6|523 L9=2/6'),
                 pre_quiz_score = c(88, NA, 12),
                 post_quiz_score = c(NA, NA, 90),
                 stringsAsFactors=FALSE)


df %>%
  mutate(ls=ifelse(!is.na(pre_quiz_score),
                   stri_replace_first_regex(ls, "^[[:alnum:][:blank:]=/]+\|", ""), ls),
         ls=ifelse(!is.na(post_quiz_score),
                   stri_replace_last_regex(ls, "\|[[:alnum:][:blank:]=/]+$", ""), ls))
##             ls pre_quiz_score post_quiz_score
## 1 425 L0=40/42             88              NA
## 2         <NA>             NA              NA
## 3   789 L8=5/6             12              90
library(dplyr)
df %>% mutate(ls = sapply(strsplit(df$ls, "\|"), function(x) x[2]))

#            ls pre_quiz_score post_quiz_score
#1 425 L0=40/42             88              NA
#2         <NA>             NA              NA
#3   789 L8=5/6             12              90

tidyr::separate() 允许您将列拆分为子列。使用 extra = "drop" 参数,它最多只能保留 length(into) 列。

library(tidyr)
separate(df, ls, c("remove", "keep"), sep="\|", extra = "drop")

#>         remove         keep pre_quiz_score post_quiz_score
#> 1 123 L0=38/42 425 L0=40/42             88              NA
#> 2         <NA>         <NA>             NA              NA
#> 3  482 L7=7/12   789 L8=5/6             12              90

我保留了第一个 | 之后的剩余部分,但如果您不需要,也可以将其删除。

我们可以使用 subbase R

df$ls <- sub("^[^|]+\|([^|]+).*", "\1", df$ls)
df
#            ls pre_quiz_score post_quiz_score
#1 425 L0=40/42             88              NA
#2         <NA>             NA              NA
#3   789 L8=5/6             12              90

说明

我们从字符串的开头 (^) 匹配一个或多个不是 | ([^|]+) 的字符,后跟一个 | (转义它 -\| 因为它是一个元字符),然后捕获一个或多个不是 | 的字符作为一组(即在括号 ([^|]+) 内),然后是字符,直到字符串的末尾 (.*) 并将其替换为捕获组的反向引用 (\1 - 因为只有一个捕获组并且它是第一个,我们用 1 表示它)