如何将 quanteda 令牌放入数据框中

How to put quanteda tokens into a dataframe

我已经使用 quanteda 标记了 10 多个文本,结果看起来像

text 1    [character]   word 1, word 2, word 3...  
text 2    [character]   word 1, word 2, word 3...  
...

此文件的类型是'tokens'。所以我想将其更改为如下数据框:

id    content  
text1  word 1  
text1  word 2  
text1  word 3  
text2  word 1  
text2  word 2  
...  

我试过了

data.frame(id = 1: length(the token file), content = unlist (the token file))

由于行的长度不同,它不起作用。
有人能帮忙吗?谢谢!

通常你会通过 dfmconvert 到达你所在的位置。

既然你没有给出例子,我将使用来自 quanteda 的 data_corpus_inaugural 语料库的一部分。

library(quanteda)
library(tidyr)
library(dplyr)

# create tokens
toks <- data_corpus_inaugural %>%
  corpus_subset(Year > 1990) %>%
  tokens(remove_punct = TRUE, remove_numbers = TRUE)

# convert to data.frame via dfm
out <- convert(dfm(toks), to = "data.frame")

# pivot to get desired outcome
my_df <- out %>% 
  pivot_longer(cols = c(!doc_id), names_to = "tokens", values_to = "freq")

my_df
# A tibble: 21,312 × 3
   doc_id       tokens    freq
   <chr>        <chr>     <dbl>
 1 1993-Clinton my            7
 2 1993-Clinton fellow        5
 3 1993-Clinton citizens      2
 4 1993-Clinton today        10
 5 1993-Clinton we           52
 6 1993-Clinton celebrate     3
 7 1993-Clinton the          89
 8 1993-Clinton mystery       1
 9 1993-Clinton of           46
10 1993-Clinton american      4
# … with 21,302 more rows

在此之后,您可以删除 freq 列,因为它包含单词的频率,但您还需要过滤掉频率为 0 的单词,因为这些单词在其他文本中没有出现在本文中。

my_df %>% 
  filter(freq != 0)

现在,如果您想以准确的顺序取回您标记化的句子,您需要做一些不同的事情。 dfm 将所有相同的单词合并为一个。这意味着第一个文本中的所有“the”都将显示为一个具有频率计数的项目。

因此,要从令牌对象中按顺序获取令牌,您需要执行其他操作。我将采用与之前相同的标记对象,toks,然后使用 as.list 进入一个命名列表,然后通过 sapply 从那里进入一个长度相等的命名数组,这样我们就可以使用 as_tibble 创建一个 data.frame 并避免您遇到的关于不同行长度的错误。后来我删除了所有具有 NA 值的标记,因为这些是对每个文本的添加,以确保所有内容的长度相同。

tok_out <- as.list(toks)

# create named array of equal lengths
x <- sapply(tok_out, '[', seq(max(lengths(tok_out))))

my_df_via_toks <- x %>% 
  as_tibble() %>% 
  pivot_longer(cols = everything(), names_to = "text", values_to = "tokens") %>% 
  filter(!is.na(tokens)) %>%  # remove NA values of each text
  arrange(text)

# A tibble: 15,700 × 2
   text         tokens   
   <chr>        <chr>    
 1 1993-Clinton My       
 2 1993-Clinton fellow   
 3 1993-Clinton citizens 
 4 1993-Clinton today    
 5 1993-Clinton we       
 6 1993-Clinton celebrate
 7 1993-Clinton the      
 8 1993-Clinton mystery  
 9 1993-Clinton of       
10 1993-Clinton American 
# … with 15,690 more rows