字符串匹配,其中字符串包含标点符号

问题描述 投票:0回答:2

我想使用grepl()找到不区分大小写的匹配项。

我想在我的数据框df的文本列中找到以下关键字列表。

# There is a long list of words, but for simplification I have provided only a subset.
I, I'm, the, and, to, a, of

我希望为每个数据行分别计算这些单词的计数。我将此单词列表定义为在代码中使用:

word_list = c('\\bI\\b','\\bthe\\b','\\band\\b','\\bto\\b','\\ba\\b','\\bof\\b')
# Note that I'm is not currently in this word_list

在我的数据框df中,我添加如下列以保留上述单词的计数:

df$I    = 0
df$IM   = 0   # this is where I need help
df$THE  = 0
df$AND  = 0
df$TO   = 0
df$A    = 0
df$OF   = 0

然后我对单词列表的每个单词使用以下for循环来迭代所需列的每一行。

# for each word of my word_list
for (i in 1:length(word_list)){ 

  # to search in each row of text response 
  for(j in 1:nrow(df)){

    if(grepl(word_list[i], df$Text[j], ignore.case = T)){   
      df[j,i+4] = (df[j,i+4])    # 4 is added to go to the specific column

    }#if 
  }#for
}#for 

对于可重现的示例,dput(df)如下:

dput(df)

structure(list(cluster3 = c(2L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 2L, 1L), userID = c(3016094L, 3042038L, 3079341L, 3079396L, 3130832L, 3130864L, 3148118L, 3148914L, 3149040L, 3150222L), Text = structure(c(3L, 4L, 2L, 9L, 6L, 10L, 7L, 1L, 5L, 8L), .Label = c("I'm alright","I'm stressed", "I am a good person.", "I don't care", "I have a difficult task", "I like it", "I think it doesn't matter", "Let's not argue about this", "Let's see if I can run", "No, I'm not in a mood"), class = "factor"), I = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), IM = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), AND = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), THE = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), TO = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), OF = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA, -10L))
r string string-matching grepl
2个回答
0
投票

我建议采用更简化的方法:

## use a named vector for the word patterns
## with the column names you want to add to `df`
word_list = c('I' = '\\bi\\b', 'THE' = '\\bthe\\b', 'AND' = '\\band\\b',
              'TO' = '\\bto\\b', 'A' = '\\ba\\b', 'OF' = '\\bof\\b', 'IM' = "\\bim")

## use `stringr::str_count` instead of `grepl`
## sapply does the looping and result gathering for us
library(stringr)
results = sapply(word_list, str_count,
   string = gsub("[[:punct:]]", "", tolower(df$Text))
)
results
#       I THE AND TO A OF IM
#  [1,] 1   3   2  1 1  1  0
#  [2,] 0   0   1  0 0  0  0
#  [3,] 0   0   0  0 0  0  0
#  [4,] 2   2   3  2 1  1  1
#  [5,] 0   0   0  1 1  0  0
#  [6,] 0   3   2  2 0  0  0
#  [7,] 1   3   0  1 1  0  0
#  [8,] 1   2   0  1 1  1  0
#  [9,] 0   0   0  0 0  0  0
# [10,] 0   0   0  1 2  0  0

## put the results into the data frame based on the names
df[colnames(results)] = data.frame(results)

由于我们依赖于矢量化的str_count,因此这应该比逐行方法快得多。


0
投票

我可以通过在双引号中添加表达式来使我的代码工作:

word_list = c('\\bI\\b',"\\bI'm\\b",'\\bthe\\b','\\band\\b','\\bto\\b','\\ba\\b','\\bof\\b')
© www.soinside.com 2019 - 2024. All rights reserved.