过滤一些字符串,但其中一些没有!用 grepl
filtering some strings but some of them not! with grepl
我正在尝试过滤数据中的一些字符串。例如,我想过滤掉 'AxxBy' 字符串,但有这个字符串 'AxxByy' 我想保留! x和y代表位数!
这是我试过的,
data <- data.frame(pair=paste(paste('A',c(seq(1:4),10,11),sep=''),paste('B',c(2,3,4,22,33,44),sep=''),sep=''))
pair
1 A1B2
2 A2B3
3 A3B4
4 A4B22
5 A10B33
6 A11B44
我想删除那些以 A1 开头但不是 A10 和 A11 的对。与 B2 相同,但保留 B22!等等
x <- c(paste('A',1,sep=''), paste('B',2,sep='')) # filtering conditions
library(dplyr)
df <- data%>%
filter(!grepl(paste(x,collapse='|'),pair))
pair
1 A2B3
2 A3B4
在这个postFiltering observations in dplyr in combination with grepl
可以通过正则表达式函数添加以 "^x|xx$"
开头的行,但如果过滤条件在管道外定义,我还没有看到任何 post。
预期输出
pair
1 A2B33
2 A3B4
3 A4B22
4 A10B33
6 A11B44
规则的拇指是;如果在 'A' 之后有两位数,则将 B 放入 AxxB 并 !grepl 在 x
输入中定义 xx 数字的所有内容。如果只有 'B' 并且给出了一个数字 'By' !grepl 'By$' 而不是 'Byy' 输入。当然这包括 'AxBy$' 和 'AxxBy$' 而已。我仍然无法概括@alistaire 解决方案!
OP 已请求 过滤掉 'AxxBy' 字符串,但希望保留字符串 'AxxByy'(其中 'x' 和 'y' 表示数字。
通常,指定要保留的内容比删除的内容更容易。为了保持符合模式 'AxxByy' 的字符串,正则表达式
"^A\d{2}B\d{2}$"
可用于 ^
表示字符串的开头,\d{2}
正好是两位数字的序列,$
表示字符串的结尾。 A
和 B
代表他们自己。
有了这个正则表达式,dplyr
和grepl()
就可以用来过滤输入数据框DF
:
library(dplyr)
#which rows are kept?
kept <- DF %>%
+ filter(grepl("^A\d{2}B\d{2}$", pair))
kept
# pair
#1 A10B33
#2 A11B44
# which rows are removed?
removed <- DF %>%
+ filter(!grepl("^A\d{2}B\d{2}$", pair))
removed
# pair
#1 A1B2
#2 A2B3
#3 A3B4
#4 A4B22
#5 AB
#6 A
#7 B
#8 A1
#9 A12
#10 B1
#11 B12
#12 AA12B34
#13 A12BB34
请注意,我添加了一些用于演示的边缘案例。
顺便说一句:如果只需要过滤向量 pair
,则不需要 dplyr
。因此,在 base R 中,替代表达式
pair[grepl("^A\d{2}B\d{2}$", pair)]
grep("^A\d{2}B\d{2}$", pair, value = TRUE)
两个 return 要保留的字符串:
[1] "A10B33" "A11B44"
而
pair[!grepl("^A\d{2}B\d{2}$", pair)]
returns 删除的字符串:
[1] "A1B2" "A2B3" "A3B4" "A4B22" "AB" "A" "B" "A1"
[9] "A12" "B1" "B12" "AA12B34" "A12BB34"
数据
正如 OP 给出的,但附加了一些边缘情况:
# create vector of test patterns using paste0() instead of paste(..., sep = "")
pair <- paste0("A", c(1:4, 10, 11), "B", c(2, 3, 4, 22, 33, 44))
# alternatvely use sprintf()
pair <- sprintf("A%iB%i", c(1:4, 10, 11), c(2, 3, 4, 22, 33, 44))
# add some edge cases
pair <- append(pair, c("AB", "A", "B", "A1", "A12", "B1", "B12", "AA12B34", "A12BB34"))
# create data frame
DF <- data.frame(pair)
DF
# pair
#1 A1B2
#2 A2B3
#3 A3B4
#4 A4B22
#5 A10B33
#6 A11B44
#7 AB
#8 A
#9 B
#10 A1
#11 A12
#12 B1
#13 B12
#14 AA12B34
#15 A12BB34
我正在尝试过滤数据中的一些字符串。例如,我想过滤掉 'AxxBy' 字符串,但有这个字符串 'AxxByy' 我想保留! x和y代表位数!
这是我试过的,
data <- data.frame(pair=paste(paste('A',c(seq(1:4),10,11),sep=''),paste('B',c(2,3,4,22,33,44),sep=''),sep=''))
pair
1 A1B2
2 A2B3
3 A3B4
4 A4B22
5 A10B33
6 A11B44
我想删除那些以 A1 开头但不是 A10 和 A11 的对。与 B2 相同,但保留 B22!等等
x <- c(paste('A',1,sep=''), paste('B',2,sep='')) # filtering conditions
library(dplyr)
df <- data%>%
filter(!grepl(paste(x,collapse='|'),pair))
pair
1 A2B3
2 A3B4
在这个postFiltering observations in dplyr in combination with grepl
可以通过正则表达式函数添加以 "^x|xx$"
开头的行,但如果过滤条件在管道外定义,我还没有看到任何 post。
预期输出
pair
1 A2B33
2 A3B4
3 A4B22
4 A10B33
6 A11B44
规则的拇指是;如果在 'A' 之后有两位数,则将 B 放入 AxxB 并 !grepl 在 x
输入中定义 xx 数字的所有内容。如果只有 'B' 并且给出了一个数字 'By' !grepl 'By$' 而不是 'Byy' 输入。当然这包括 'AxBy$' 和 'AxxBy$' 而已。我仍然无法概括@alistaire 解决方案!
OP 已请求 过滤掉 'AxxBy' 字符串,但希望保留字符串 'AxxByy'(其中 'x' 和 'y' 表示数字。
通常,指定要保留的内容比删除的内容更容易。为了保持符合模式 'AxxByy' 的字符串,正则表达式
"^A\d{2}B\d{2}$"
可用于 ^
表示字符串的开头,\d{2}
正好是两位数字的序列,$
表示字符串的结尾。 A
和 B
代表他们自己。
有了这个正则表达式,dplyr
和grepl()
就可以用来过滤输入数据框DF
:
library(dplyr)
#which rows are kept?
kept <- DF %>%
+ filter(grepl("^A\d{2}B\d{2}$", pair))
kept
# pair
#1 A10B33
#2 A11B44
# which rows are removed?
removed <- DF %>%
+ filter(!grepl("^A\d{2}B\d{2}$", pair))
removed
# pair
#1 A1B2
#2 A2B3
#3 A3B4
#4 A4B22
#5 AB
#6 A
#7 B
#8 A1
#9 A12
#10 B1
#11 B12
#12 AA12B34
#13 A12BB34
请注意,我添加了一些用于演示的边缘案例。
顺便说一句:如果只需要过滤向量 pair
,则不需要 dplyr
。因此,在 base R 中,替代表达式
pair[grepl("^A\d{2}B\d{2}$", pair)]
grep("^A\d{2}B\d{2}$", pair, value = TRUE)
两个 return 要保留的字符串:
[1] "A10B33" "A11B44"
而
pair[!grepl("^A\d{2}B\d{2}$", pair)]
returns 删除的字符串:
[1] "A1B2" "A2B3" "A3B4" "A4B22" "AB" "A" "B" "A1"
[9] "A12" "B1" "B12" "AA12B34" "A12BB34"
数据
正如 OP 给出的,但附加了一些边缘情况:
# create vector of test patterns using paste0() instead of paste(..., sep = "")
pair <- paste0("A", c(1:4, 10, 11), "B", c(2, 3, 4, 22, 33, 44))
# alternatvely use sprintf()
pair <- sprintf("A%iB%i", c(1:4, 10, 11), c(2, 3, 4, 22, 33, 44))
# add some edge cases
pair <- append(pair, c("AB", "A", "B", "A1", "A12", "B1", "B12", "AA12B34", "A12BB34"))
# create data frame
DF <- data.frame(pair)
DF
# pair
#1 A1B2
#2 A2B3
#3 A3B4
#4 A4B22
#5 A10B33
#6 A11B44
#7 AB
#8 A
#9 B
#10 A1
#11 A12
#12 B1
#13 B12
#14 AA12B34
#15 A12BB34