使用grep删除包含年份少于2014的任何字符串

时间:2017-05-09 16:19:37

标签: r regex grep

编辑添加更多上下文和数据5/12/2017

在Windows上使用R版本3

我有一个数据框data2:

'data.frame':   1504 obs. of  14 variables:
$ Member.Name       : chr  "A" "B" "C"... 
$ MSTATUS           : Factor w/ 14 levels "","ACTIVE","ACTIVE;CHANGEDROLES;NONQUALIF",..: 13 2 2 2 2 4 13 13 2 13 ...
$ MCAT              : Factor w/ 9 levels "","EDNEWCLASS",..: 5 4 9 6 6 6 9 9 4 4 ...
$ SALUTATION        : Factor w/ 822 levels "","Aaron","Abigail",..: 285 2 2 2 4 4 4 4 5 5 ...
$ MEM_SUBCATEGORY   : Factor w/ 22 levels "","AGENCYCEO",..: 22 6 8 15 8 6 8 1 6 6 ...
$ MEM_SUBTYPE       : Factor w/ 25 levels "","AGENCY","AGENCYCEO",..: 24 6 6 20 6 6 6 6 6 6 ...
$ COUNTRY           : Factor w/ 33 levels "","AE","AT","AU",..: 33 33 33 33 7 33 33 33 33 33 ...
$ F500              : Factor w/ 243 levels "","#1406 on Forbes Global 2000 ($11B)",..: 1 1 96 1 242 1 147 1 1 76 ...
$ OPT_LINE          : Factor w/ 1467 levels "","(Formerly) Condé Nast",..: 1 1170 609 1333 251 1427 444 258 814 1207 ...
$ FLAGS             : chr  "2014PAGEJAMPARTICIPANT, \nPHOTO" "" "PUFOUNDINGMEMBER" "2014FLESPEAKER" ...
$ FLAGS_DESCR       : chr  "2014 Page Jam Participant, \nPhoto on File" "" "Page Up Founding Member" "2014 Future Leaders Experience Speaker" ...
$ Enroll.Date       : Date, format: "2012-12-04" "2010-08-24" "2013-09-20" "2013-05-06" ...
$ Expiration.Date   : Date, format: "2014-12-31" "2017-12-31" "2017-12-31" "2017-12-31" ...
$ Sponsorship.Amount: num  0 0 0 0 0 0 0 0 0 0 ...

对于FLAGS变量,我想删除包含少于2014年的年份的所有行元素。

head(data2$FLAGS, n=3)
[1] "2011PRESIDENTS, \n2012CHAIRMANSCOUNCIL, \n2016CHAIRCOUNCIL" ""                                                          
[3] "2012COI"     

所以FLAGS看起来像:

head(data2$FLAGS, n=3)
[1] "\n2016CHAIRCOUNCIL" ""                                                          
[3] "" 

没有值的行可以是空白或NA,但是如果一行确实包含年份>> 2014的事件和年份<2014的事件而不是仅删除少于2014年的事件并保留行中的其他事件。

2 个答案:

答案 0 :(得分:2)

这个正则表达式适用于您的示例。我们的想法是将那些失败的元素与年份的前3个字符相匹配。

FLAGS[-grep("20(0|1[0123])", FLAGS)]
[1] "2014PAGEJAMPARTICIPANT, \nPHOTO" "\n2014PAGEJAMPARTICIPANT"  "\n2014PUSPONSOR, \nPHOTO"

或者,使用反转,你有

FLAGS[grep("20(0|1[0123])", FLAGS, invert=TRUE)]

请注意,它不会在2000年之前捕获,如果有其他数字&#34;你应该保持谨慎。向量中的值。

要返回相同长度的向量,并使用NAs替换前几年,您可以使用is.na<-grepl这样

is.na(FLAGS) <- grepl("20(0|1[0123])", FLAGS)

原始数据

FLAGS<-c("2014PAGEJAMPARTICIPANT, \nPHOTO", "2001ANNUALCONFERENCECOMM", 
         "\n2011GOVERNANCE", "\n2014PAGEJAMPARTICIPANT", "2013NEWMEMBERNOMINATOR", 
         "\n2014PUSPONSOR, \nPHOTO")

给出了OP的第二个问题。以下或多或少有效:

sapply(strsplit(FLAGS, ","),
       function(x) paste(gsub("(\\n)?20(0|1[0123]).*?(, |$)", "", trimws(x)), collapse=" "))

[1] "  2016CHAIRCOUNCIL" ""                   ""

请注意&#34; \ n&#34;在开头缺少,并且在第一个元素的开头有一个额外的(一组)空格。 &#34; \ n&#34;被移除trimws。这使得字符串更容易使用。通过在trimws中包含上述表达式,可以删除其他空格,例如trimws(sapply(strsplit(...)))

其他数据

FLAGS <- c("2011PRESIDENTS, \n2012CHAIRMANSCOUNCIL, \n2016CHAIRCOUNCIL", "", "2012COI")

答案 1 :(得分:2)

以下是使用stringr包的一种解决方案:

library(stringr)
FLAGS[sapply(str_extract_all(FLAGS, '[0-9]{4}'),
             function(x) !any(as.integer(x) < 2014))]

此解决方案假设您在每个值中可能有一年以上的时间。如果不是这样,你可以做一些更简单的事情:

FLAGS[as.integer(str_extract(FLAGS, '[0-9]{4}')) >= 2014]

假设FLAGS如下:

FLAGS
[1] "2014PAGEJAMPARTICIPANT, \nPHOTO" "2001ANNUALCONFERENCECOMM"       
[3] "\n2011GOVERNANCE"                "\n2014PAGEJAMPARTICIPANT"       
[5] "2013NEWMEMBERNOMINATOR"          "\n2014PUSPONSOR, \nPHOTO"       

你得到的结果为:

[1] "2014PAGEJAMPARTICIPANT, \nPHOTO" "\n2014PAGEJAMPARTICIPANT"       
[3] "\n2014PUSPONSOR, \nPHOTO"       

根据上述问题编辑编辑答案

您只能保留2014年或以上的值,并填写NAs,否则如下:

data2$FLAGS <- ifelse(as.integer(str_extract(data2$FLAGS, '\\d+')) >= 2014,
                      data2$FLAGS, NA)

结果如下:

[1] "2014PAGEJAMPARTICIPANT, \nPHOTO" NA                               
[3] NA                                "\n2014PAGEJAMPARTICIPANT"       
[5] NA                                "\n2014PUSPONSOR, \nPHOTO"