1

我正在使用tidytext(和tidyverse)来分析一些文本数据(如在Tidy Text Mining with R中)。

我的输入文本文件myfile.txt,看起来像这样:

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

有60个左右的部分。

我想section_name用字符串"Category 1 Name""Category 2 Name"作为相应行的值生成一列。例如,我有

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()

tidiedtext它为每行的相应部分编号添加一列。

是否可以在调用中添加一行以mutate()添加这样的列?还是我应该使用另一种方法?

4

2 回答 2

1

我不希望你重写整个脚本,但我只是发现这个问题很有趣,并想添加一个基本的 R 暂定:

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)
}

使用名为的文件进行测试ipsum_data.txt

parse_data('ipsum_data.txt')

产量:

 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   

该文件ipsum_data.txt包含:

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

我希望这被证明是有用的。

于 2017-02-23T22:17:51.880 回答
0

grepl为了简单起见,这是一种使用if_elseand的方法tidyr::fill,但原始方法没有任何问题;它与 tidytext 书中使用的非常相似。另请注意,添加行号后的过滤将使一些不存在。如果重要,请在filter.

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

或者,如果您只想格式化已有的号码,只需添加section_name = paste('Category', section_id, 'Name')到您的mutate通话中即可。

于 2017-02-23T21:34:41.523 回答