2017-02-23 1 views
1

Ich verwende tidytext (und die tidyverse), um einige Textdaten zu analysieren (wie in Tidy Text Mining with R).Einfache Abschnittbeschriftung mit tidtext für Klartexteingabe

Meine Eingabetextdatei, myfile.txt, sieht wie folgt aus:

# Section 1 Name 
Lorem ipsum dolor 
sit amet ... (et cetera) 
# Section 2 Name 
<multiple lines here again> 

mit 60 oder so Abschnitte.

Ich möchte eine Spalte section_name mit den Strings "Category 1 Name" oder "Category 2 Name" als Werte für die entsprechenden Zeilen generieren. Zum Beispiel habe ich

library(tidyverse) 
library(tidytext) 
library(stringr) 

fname <- "myfile.txt" 
all_text <- readLines(fname) 
all_lines <- tibble(text = all_text) 
tidiedtext <- all_lines %>% 
    mutate(linenumber = row_number(), 
     section_id = cumsum(str_detect(text, regex("^#", ignore_case = TRUE)))) %>% 
    filter(!str_detect(text, regex("^#"))) %>% 
    ungroup() 

, die für jede Zeile eine Spalte in tidiedtext für die entsprechende Abschnittsnummer hinzufügt.

Ist es möglich, dem Aufruf an mutate() eine einzelne Zeile hinzuzufügen, um eine solche Spalte hinzuzufügen? Oder gibt es einen anderen Ansatz, den ich verwenden sollte?

Antwort

0

Hier ist ein Ansatz mit grepl zur Vereinfachung mit if_else und tidyr::fill, aber es ist nichts falsch mit dem ursprünglichen Ansatz; Es ist ziemlich ähnlich zu einem, das im tidytext Buch verwendet wird. Beachten Sie auch, dass das Filtern nach dem Hinzufügen von Zeilennummern einige nicht vorhanden macht. Wenn es darauf ankommt, fügen Sie Zeilennummern nach filter hinzu.

library(tidyverse) 

text <- '# Section 1 Name 
Lorem ipsum dolor 
sit amet ... (et cetera) 
# Section 2 Name 
<multiple lines here again>' 

all_lines <- data_frame(text = read_lines(text)) 

tidied <- all_lines %>% 
    mutate(line = row_number(), 
      section = if_else(grepl('^#', text), text, NA_character_)) %>% 
    fill(section) %>% 
    filter(!grepl('^#', text)) 

tidied 
#> # A tibble: 3 × 3 
#>       text line   section 
#>       <chr> <int>   <chr> 
#> 1   Lorem ipsum dolor  2 # Section 1 Name 
#> 2 sit amet ... (et cetera)  3 # Section 1 Name 
#> 3 <multiple lines here again>  5 # Section 2 Name 

Oder wenn Sie nur die Zahlen formatieren möchten haben Sie bereits erhalten, fügen Sie einfach section_name = paste('Category', section_id, 'Name') zu Ihrem mutate Anruf.

+0

Danke! Das ist ziemlich genau das, wonach ich gesucht habe. – weinerjm

1

Ich will Sie nicht Ihre gesamte Skript haben, neu zu schreiben, aber ich fand nur die Frage interessant und dachte an eine Basis R versuchsweise hinzufügen:

parse_data <- function(file_name) { 
    all_rows <- readLines(file_name) 
    indices <- which(grepl('#', all_rows)) 
    splitter <- rep(indices, diff(c(indices, length(all_rows)+1))) 
    lst <- split(all_rows, splitter) 
    lst <- lapply(lst, function(x) { 
    data.frame(section=x[1], value=x[-1], stringsAsFactors = F) 
    }) 
    line_nums = seq_along(all_rows)[-indices] 
    df <- do.call(rbind.data.frame, lst) 
    cbind.data.frame(df, linenumber = line_nums) 
} 

Testing mit einer Datei namens ipsum_data.txt:

parse_data('ipsum_data.txt') 

ergibt:

text      section   linenumber 
Lorem ipsum dolor   # Section 1 Name 2   
sit amet ... (et cetera) # Section 1 Name 3   
<multiple lines here again> # Section 2 Name 5 

Die Datei ipsum_data.txt enthält:

# Section 1 Name 
Lorem ipsum dolor 
sit amet ... (et cetera) 
# Section 2 Name 
<multiple lines here again> 

Ich hoffe, das erweist sich als nützlich.

+0

Danke für die Antwort. Das ist sehr hilfreich. Es ist keine große Sache für mich, das Skript neu zu schreiben, aber ich denke, die andere Lösung ist mehr, was ich in Bezug auf Prägnanz gesucht habe. – weinerjm