根据R中各列中的值选择行

时间:2014-05-07 16:02:26

标签: r row subset

我的data.frame的三列包含主题。我想为不同的主题将这个data.frame分组。例如。如果我想要一个主题为“apple”的data.frame,那么如果“apple”一词出现在三列中的一列中,则应选择该行。

doc    <- c("blabla1", "blabla2", "blabla3", "blabla4")
subj.1 <- c("apple", "prune", "coconut", "berry")
subj.2 <- c("coconut", "apple", "cherry", "banana and prune")
subj.3 <- c("berry", "banana", "apple and berry", "pear", "prune")
subjects <- c("apple", "prune", "coconut", "berry", "cherry", "pear", "banana")

mydf <- data.frame(doc, subj.1, subj.2, subj.3, stringsAsFactors=FALSE) 
mydf

#       doc   subj.1            subj.2             subj.3
# 1 blabla1    apple           coconut              berry
# 2 blabla2    prune             apple             banana
# 3 blabla3  coconut            cherry    apple and berry
# 4 blabla4    berry  banana and prune               pear

主题“apple”的输出应如下所示:

#       doc   subj.1            subj.2             subj.3
# 1 blabla1    apple           coconut              berry
# 2 blabla2    prune             apple             banana
# 3 blabla3  coconut            cherry    apple and berry

EDIT1: 另外,假设我有大约200个不同的主题,因此我需要200个不同的数据框架。我怎么能这样做?

我尝试了循环方法:

mylist <- vector('list', length(subjects))

for(i in 1:length(subjects)) {
pattern <- subjects[i]
filter <- grepl(pattern, ignore.case=T, mydf$subj.1)
      grepl(pattern, ignore.case=T, mydf$subj.2)
      grepl(pattern, ignore.case=T, mydf$subj.3)
    subDF <- panel[filter,] 

mylist[[i]] <- subDF
  }

但是有错误:

Error in grepl(pattern, ignore.case = T, panel$SUBJECT.1) : 
 invalid regular expression 'C++ PROGRAMMING', reason 'Invalid use of repetition operators'

EDIT2:哦,我看到,在原始data.frame中,其中一个主题是“C ++ PROGRAMMING”。可能“++”会导致错误吗?

1 个答案:

答案 0 :(得分:2)

您可以使用grepl功能:

pattern <- 'apple'
filter <- grepl(pattern, ignore.case=T, mydf$subj.1) | 
          grepl(pattern, ignore.case=T, mydf$subj.2) | 
          grepl(pattern, ignore.case=T, mydf$subj.3)
subDF <- mydf[filter,] 

> subDF 
      doc  subj.1  subj.2          subj.3
1 blabla1   apple coconut           berry
2 blabla2   prune   apple          banana
3 blabla3 coconut  cherry apple and berry

编辑:

关于你关于for循环的问题,我没有看到使用它的任何问题,我怀疑使用apply-family函数会在执行时间方面带来很多好处。

对于错误,问题是传递给grepl的字符串模式必须是有效的正则表达式,但'+'是一个特殊字符,因此不允许'++'。<登记/> 无论如何,如果您只想检查列中是否包含主题字符串,可以通过设置grepl参数fixed=TRUE来禁用正则表达式引擎( 这意味着pattern是一个匹配的字符串)。

唯一的缺点是ignore.case无法与fixed = TRUE一起使用。