Как разобрать определенный фрагмент текста?

Моя цель — выделить определенный раздел в наборе документов Word по ключевым словам. У меня возникают проблемы с анализом определенных разделов текста из большого набора данных текстовых файлов. Первоначально набор данных выглядел так: «заголовок 1» и «заголовок 2» обозначали начало и конец интересующего меня текста, а несущественные слова обозначали часть текстового файла, которая меня не интересует:

**Text**           **Text File** 
title one           Text file 1
sentence one        Text file 1
sentence two        Text file 1
title two           Text file 1
unimportant words   Text file 1
title one           Text file 2
sentence one        Text file 2

Затем я использовал as.character, чтобы преобразовать данные в символы, и использовал unnest_tokens, чтобы привести данные в порядок.

df <- data.frame(lapply(df, as.character), stringsAsFactors=FALSE)
tidy_df <- df %>% unnest_tokens(word, Text, token = "words")

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

filtered_resume <- lapply(tidy_resume, (tidy_resume %>% select(Name) %>% filter(title:two)))

person Danielle Strauss    schedule 16.07.2018    source источник


Ответы (2)


Не знаком с пакетом tidytext, поэтому вот альтернативное базовое решение R. Используя этот расширенный пример данных (код создания включен внизу):

> df
                Text        File
1          title one Text file 1
2       sentence one Text file 1
3       sentence two Text file 1
4          title two Text file 1
5  unimportant words Text file 1
6          title one Text file 2
7       sentence one Text file 2
8       sentence two Text file 2
9     sentence three Text file 2
10         title two Text file 2
11 unimportant words Text file 2

Создайте функцию, которая создает отдельный столбец, указывающий, следует ли сохранить или удалить данную строку, на основе значения в столбце Text. Подробности в комментариях:

get_important_sentences <- function(df_) {
  # Create some variables for filtering
  val = 1
  keep = c()

  # For every text row
  for (x in df_$Text) {
    # Multiply the current val by 2
    val = val * 2

    # If the current text includes "title",
    # set val to 1 for 'title one', and to 2
    # for 'title two'
    if (grepl("title", x)) {
      val = ifelse(grepl("one", x), 1, 0)
    }

    # append val to keep each time
    keep = c(keep, val)
  }

  # keep is now a numeric vector- add it to
  # the data frame
  df_$keep = keep

  # exclude any rows where 'keep' is 1 (for
  # 'title one') or 0 (for 'title 2' or any
  # unimportant words). Also, drop the
  return(df_[df_$keep > 1, c("Text", "File")])
}

Затем вы можете вызвать это либо для всего фрейма данных:

> get_important_sentences(df)
            Text        File
2   sentence one Text file 1
3   sentence two Text file 1
7   sentence one Text file 2
8   sentence two Text file 2
9 sentence three Text file 2

Или для каждого файла-источника с lapply:

> lapply(split(df, df$File), get_important_sentences)
$`Text file 1`
          Text        File
2 sentence one Text file 1
3 sentence two Text file 1

$`Text file 2`
            Text        File
7   sentence one Text file 2
8   sentence two Text file 2
9 sentence three Text file 2

Данные:

df <-
  data.frame(
    Text = c(
      "title one",
      "sentence one",
      "sentence two",
      "title two",
      "unimportant words",
      "title one",
      "sentence one",
      "sentence two",
      "sentence three",
      "title two",
      "unimportant words"
    ),
    File = c(rep("Text file 1", 5), rep("Text file 2", 6)),
    stringsAsFactors = FALSE
  )
person Luke C    schedule 16.07.2018

Если вам нужен вариант tidyverse, который включает в себя очень мало строк кода, взгляните на него. Вы можете использовать case_when() и str_detect(), чтобы найти строки в вашем фрейме данных, которые содержат сигналы для важных/неважных.

library(tidyverse)

df1 <- df %>%
  mutate(important = case_when(str_detect(Text, "title one") ~ TRUE,
                               str_detect(Text, "title two") ~ FALSE))
df1 
#> # A tibble: 11 x 3
#>    Text              File        important
#>    <chr>             <chr>       <lgl>    
#>  1 title one         Text file 1 TRUE     
#>  2 sentence one      Text file 1 NA       
#>  3 sentence two      Text file 1 NA       
#>  4 title two         Text file 1 FALSE    
#>  5 unimportant words Text file 1 NA       
#>  6 title one         Text file 2 TRUE     
#>  7 sentence one      Text file 2 NA       
#>  8 sentence two      Text file 2 NA       
#>  9 sentence three    Text file 2 NA       
#> 10 title two         Text file 2 FALSE    
#> 11 unimportant words Text file 2 NA

Теперь вы можете использовать fill() из tyr, чтобы заполнить эти значения.

df1 %>%
  fill(important, .direction = "down")
#> # A tibble: 11 x 3
#>    Text              File        important
#>    <chr>             <chr>       <lgl>    
#>  1 title one         Text file 1 TRUE     
#>  2 sentence one      Text file 1 TRUE     
#>  3 sentence two      Text file 1 TRUE     
#>  4 title two         Text file 1 FALSE    
#>  5 unimportant words Text file 1 FALSE    
#>  6 title one         Text file 2 TRUE     
#>  7 sentence one      Text file 2 TRUE     
#>  8 sentence two      Text file 2 TRUE     
#>  9 sentence three    Text file 2 TRUE     
#> 10 title two         Text file 2 FALSE    
#> 11 unimportant words Text file 2 FALSE

Создано 14 августа 2018 г. с помощью пакета reprex (v0.2.0).

На этом этапе вы можете filter(important) сохранить только тот текст, который вам нужен, а затем вы можете использовать функции из tidytext для анализа оставшегося важного текста.

person Julia Silge    schedule 14.08.2018