从spss切换后,我对R还是相当陌生,但需要在该项目中使用R。我正在从人的excel文件中读取数据,每个人的唯一标识符是他们的英国国民保险号码,但是我需要删除任何不包含正确格式的NINO的行,即AB123456A。
数据中列出了某些类型的“ NINO”,由于它们与格式不完全匹配,因此我需要将其删除。
我在网上找到了此正则表达式以验证NINO的格式。
/ ^ [A-CEGHJ-PR-TW-Z] {1} [A-CEGHJ-NPR-TW-Z] {1} [0-9] {6} [AD] {1} $ / i
我尝试在下面的代码中运行它,但是虽然没有显示错误消息,但它也不会从数据集中删除任何行。
DEP_Programmes %>%
filter(!grepl("/^[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}[0-9]{6}[A-D]{1}$/i", DEP_Programmes$NiNo)) %>%
count(Programme)
有什么建议吗?拜托,谢谢。
答案 0 :(得分:1)
传递给grepl
的正则表达式不使用任何定界符,并且如果您希望不区分大小写,请使用ignore.case
选项而不是/i
:
DEP_Programmes %>%
filter(!grepl("^[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}[0-9]{6}[A-D]{1}$", NiNo, ignore.case=TRUE)) %>%
count(Programme)
注意:您当前的正则表达式看起来很像PHP或JavaScript。
答案 1 :(得分:1)
摘自Wikipedia:
[国民保险]号的格式为两个前缀字母, 六位数字和一个后缀字母。 [...]前两个字母都不能为D,F,I,Q,U 或V。第二个字母也不能为O。前缀BG,GB,NK,KN, 未分配TN,NT和ZZ。 [...]后缀字母是A, B,C或D (source)。
因此,您发现的正则表达式几乎正确,但是应该删除前导和尾随字符。一点测试:
regex <- "^[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}[0-9]{6}[A-D]{1}$"
test <- c("AB123456A", "******69B", "cms1234", "BCN8888855555",
"AB 123456 A", NA, "QQ123456C")
grepl(regex, test)
# [1] TRUE FALSE FALSE FALSE FALSE FALSE FALSE
检查this cheatsheet以供参考。
在原始代码中,该代码应如下所示:
DEP_Programmes %>%
filter(grepl("^[A-CEGHJ-PR-TW-Z]{1}[A-CEGHJ-NPR-TW-Z]{1}[0-9]{6}[A-D]{1}$", NiNo)) %>% # omit DEP_Programmes$ inside dplyr pipe
count(Programme)
请注意,在过滤器中,将保留TRUE
值,并删除FALSE
值。通过添加前导!
,您可以反转选择,这意味着您的TRUE
值将被删除(据我了解,您不需要)。这就是为什么您的原始代码没有被删除的原因。由于正则表达式不是正则表达式的惯用语,而是其他某种语言,因此所有字符串均为FALSE
。反过来,一切都得以保留。