根据R中的多个字符串匹配条件从数据帧中过滤出行

时间:2014-08-12 21:32:48

标签: r string-matching

我正在使用R中的read.table()读取外部数据:

student_record <- read.table("Address of data",fill = TRUE,col.names=c("student_id","name"))

学生ID是一个长度为20个字符的字符串,格式为STU01000001010001001,我希望保留学生ID满足以下条件的行:

   ( 0 – 2 = STU) AND
(5 – 9  != 11111) AND
(10 – 11 != (00 or 10)) AND
(12 – 17  != 111111) AND
(18-19 = 04)

此处02等代表学生ID中的字符索引。如何使用此类过滤条件过滤掉记录?

我在read.table()之后执行此操作以过滤:

stu_record <- student_record[grepl("^STU.{2}(?!11111).(?!(00|10)).(?!111111).04", student_record[,1], perl=T),]

但输出似乎不正确,因为一切都被过滤掉了,我得到一个空框架

当我执行此操作时:

stu_record <- student_record[grepl("^STU.{2}(?!11111).(?!(00|10)).(?!111111)04", student_record[,1], perl=T),]  

然后我看到了记录,但它们似乎不正确,因为我可以看到像STU13120600500000002这样的记录不应该出现,因为最后两个索引应该是04

UPDATE:执行上述命令后我看到的几行是(ids不能正确过滤,因为两位数应该是04,但我看到01):

       student_id         Name    
  "STU01115000000000001"  "A"   
  "STU01115000000000001"  "B"   
  "STU01115000000000001"  "C"   
  "STU01115000000000001"  "D"   
  "STU01115000000000001"  "E"   
  "STU01115000000000001"  "F"   
  "STU01115000000000001"  "G"   
  "STU01115000000000001"  "H"   
  "STU01115000000000001"  "I"

虽然应该存在但过滤掉的一些ID是:

      "STU01155000000000004"  "F"   
      "STU01135000000000004"  "G"   
      "STU01145000000000004"  "H"   
      "STU01125000000000004"  "I"

注意:字符串中有某些索引没有像索引34这样的条件,没有过滤条件,所以它们可以是任何东西。< / p>

3 个答案:

答案 0 :(得分:2)

这应该有效。我编了一个测试字符串。

string <- c("STU0100010", "STU0100010", "STU0300010", "STU0100090")

grepl("^STU(?!01).*(?!01|90)$", string, perl = T)
[1] FALSE FALSE  TRUE FALSE

grep函数在向量中查找以STU开头的字符串,但后面没有01(使用负前瞻断言)并且末尾没有01或90(另一个负前瞻和字符串结尾)锚)。

答案 1 :(得分:1)

您可以使用substr函数:

# example data
df <- 
data.frame(
student_id=c('STUx1000xx','STU00110xx','STU01008bb','STU01090aa'),
name=c('A','B','C','D'),stringsAsFactors=F)

# > df
#   student_id name
# 1 STUx1000xx    A
# 2 STU00110xx    B
# 3 STU01008bb    C
# 4 STU01090aa    D

# create filter using substr function
condition <- substr(df$student_id,1,3) == 'STU' &
             substr(df$student_id,5,6) != '01' &
             substr(df$student_id,7,8) != '01' &
             substr(df$student_id,7,8) != '90' 

filtered <- df[condition,]

# > filtered
#   student_id name
# 1 STUx1000xx    A
# 3 STU01008bb    C

编辑:

新条件应该是:

condition <- substr(df$student_id,1,3) == 'STU' &
             substr(df$student_id,6,10) != '11111' &
             substr(df$student_id,11,12) != '00' &
             substr(df$student_id,11,12) != '10' &
             substr(df$student_id,13,18) != '111111' &
             substr(df$student_id,19,20) == '04'

答案 2 :(得分:1)

使用@digEmAll中的df

df[grepl("^STU.(?!01).{2}(?!(01|90))", df[,1], perl=T),]
#    student_id name
#1 STUx1000xx    A
#3 STU01008bb    C