Подсчитайте вхождения определенных слов из строки фрейма данных в R

У меня есть набор данных с 2 столбцами и несколькими строками. идентификатор первого столбца, второй столбец - текст, который ему принадлежит.

Я хочу добавить больше столбцов, которые суммируют, сколько раз определенная строка появляется в тексте из строки. строка будет "\n Положительная\n", "\n Нейтральная\n", "\n Отрицательная\n"`

Пример набора данных:

Id, Content
2356, I like cheese.\n  Positive\nI don't want to be here.\n Negative\n
3456, I am alone.\n Neutral\n

В конце должно получиться так

Id, Content,Positiv, Neutral, Negativ
2356, I like cheese.\n  Positive\nI don't want to be here.\n Negative\n,1 ,0 ,1
3456, I am alone.\n Neutral\n, 0, 1, 0

Прямо сейчас я попробовал это так, но он не дает правильных ответов:

getCount1 <- function(data, keyword)
{
Positive <- str_count(Dataset$CONTENT, keyword)
return(data.frame(data,Positive))
}
Stufe1 <-getCount1(Dataset,'\n Positive\n')
################################################################
getCount2 <- function(data,  keyword)
{
Neutral <- str_count(Stufe1$CONTENT, keyword)
return(data.frame(data,Neutral))
}
Stufe2 <-getCount2(Stufe1,'\n  Neutral\n')
#####################################################
getCount3 <- function(data,  keyword)
{
Negative <- str_count(Stufe2$CONTENT, keyword)
return(data.frame(data,Negative))
}
Stufe3 <-getCount3(Stufe2,'\n  Negative\n')

person Carlo    schedule 03.07.2014    source источник
comment
И в этом случае совпадение должно быть нулевым, верно? Найдите gregexpr и regmatches в качестве отправной точки. Или есть несколько полезных пакетов, таких как stringr или stringi.   -  person A5C1D2H2I1M1N2O1R2T1    schedule 03.07.2014
comment
Добро пожаловать в StackOverflow! Прочтите информацию о том, как задать хороший вопрос и как создать минимально воспроизводимый пример. Это значительно облегчит другим людям помощь.   -  person Jaap    schedule 03.07.2014


Ответы (4)


Я предполагаю, что это то, что вам нужно

Пример данных

id <- c(1:4)
text <- c('I have a Dataset with 2 columns a',
          'nd multiple rows. first column ID', 'second column the text which',
          'n the text which belongs to it.')
dataset <- data.frame(id,text)

Функция для нахождения количества

library(stringr)
getCount <- function(data,keyword)
{
  wcount <- str_count(dataset$text, keyword)
  return(data.frame(data,wcount))
}

Вызов getCount должен дать обновленный набор данных

> getCount(dataset,'second')
  id                              text wcount
  1   I have a Dataset with 2 columns a      0
  2   nd multiple rows. first column ID      0
  3        second column the text which      1
  4     n the text which belongs to it.      0
person on_the_shores_of_linux_sea    schedule 03.07.2014
comment
Это работает очень хорошо, но все еще есть проблема, потому что я ищу не конкретное слово, а выражение, если я сделаю это с помощью Positive, это сработает. Но если я хочу сделать это с выражением \n Positive\n, это не так. - person Carlo; 03.07.2014
comment
Можете ли вы обновить вопрос с лучшим образцом? Я только что попробовал с «\n Positive», и это дало мне правильный подсчет. - person on_the_shores_of_linux_sea; 04.07.2014
comment
Я обновил лучший образец и опубликовал код на основе вашего решения, но в моем случае он не работает. Это работает, только если я ищу положительный, нейтральный и отрицательный. - person Carlo; 29.07.2014

Чтобы предложить некоторые альтернативы, давайте начнем с немного измененной версии набора данных @on_the_shores_of_linux_sea.

id <- c(1:4)
text <- c('I have a Dataset with 2 columns a',
          'nd multiple rows. first column ID rows', 
          'second column the text which',
          'n the text which belongs to it.')
dataset <- data.frame(id,text)

Придерживаясь базовых функций R, вы могли бы придумать функцию, подобную этой.

wordCounter <- function(invec, word, ...) {
  vapply(regmatches(invec, gregexpr(word, invec, ...)), length, 1L)
}

Вы бы использовали это так:

## allows other arguments to gregexpr
wordCounter(dataset$text, "id", ignore.case = TRUE) 
# [1] 0 1 0 0
wordCounter(dataset$text, "id")
# [1] 0 0 0 0
wordCounter(dataset$text, "rows")
# [1] 0 2 0 0
wordCounter(dataset$text, "second", ignore.case = TRUE)
# [1] 0 0 1 0

Другой альтернативой, если вы хотите использовать готовые решения, было бы использование пакета "stringi", который имеет отличный набор функций stri_count*. Здесь я использовал stri_count_fixed:

library(stringi)
stri_count_fixed(dataset$text, "rows")
# [1] 0 2 0 0
person A5C1D2H2I1M1N2O1R2T1    schedule 03.07.2014

Это также можно сделать без загрузки какой-либо дополнительной библиотеки, как указал Ананда. Мое решение было бы таким, при условии, что таблица с двумя столбцами называется dataset, а строка для поиска - mystring:

countOccurr = function(text,motif) {
 res = gregexpr(motif,text,fixed=T)[[1]]
 ifelse(res[1] == -1, 0, length(res))
}

dataset = cbind(dataset, count = vapply(dataset[,2], countOccurr, 1, motif=mystring))

Остерегайтесь, что второй столбец вашего фрейма данных должен иметь характер режима, если вы хотите избежать проблем (фрейм данных, указанный в качестве образца данных @on-the-shores-of-linux-sea, сохраняет фактор режима, что хорошо с его решением а не с моей). В противном случае используйте as.character(dataset[,2]) для броска.

person jaybee    schedule 03.07.2014

Почему бы просто не:

dataset$Positiv <- str_count(dataset$Content, 'Positiv')
dataset$Neutral <- str_count(dataset$Content, 'Neutral')
dataset$Negativ <- str_count(dataset$Content, 'Negativ')
person Ilona    schedule 17.04.2020