Для цикла при извлечении ключевых слов с UDPIPE в R

Давайте начнем с воспроизводимого примера, который представляет собой фрейм данных с именем key состоит из 8 столбцов и 3 строк:

key <- structure(c("Make Professional Maps with QGIS and Inkscape", 
"Gain the skills to produce original, professional, and aesthetically pleasing maps using free software", 
"English", "Inkscape 101 for Beginners - Design Vector Graphics", 
"Learn how to create and design vector graphics for free!", "English", 
"Design & Create Vector Graphics With Inkscape 2016", "The Beginners Guide to designing and creating Vector Graphics with Inkscape. No Experience needed!", 
"English", "Design a Logo for Free in Inkscape", "Learn from an award winning, published logo design professional!", 
"English", "Inkscape - Beginner to Pro", "If you want to have a decent learning curve, you are new to the program or even in design, this course is for you.", 
"English", "Creating 2D Textures in Inkscape", "A guide to creating colorful and interesting textures in inkscape.", 
"English", "Vector Art in Inkscape - Icon Design | Make Vector Graphics", 
"Learn Icon Design by creating Vector Graphics using the .SVG and PNG format with the Free Software Inkscape!", 
"English", "Inkscape and Bootstrap 3 -> Responsive Web Design!", 
"Design responsive websites using Free tools Inkscape and Bootstrap 3! Mood Boards and Style Tiles to Mobile First!", 
"English"), .Dim = c(3L, 8L), .Dimnames = list(c("Title", "Short_Description", 
"Language"), c("1", "2", "4", "5", "6", "9", "13", "15")))

Я хотел бы извлечь ключевые слова каждого столбца независимо. Для этой цели я использую udpipe пакет от R.

Поскольку я хочу запустить функции в каждом столбце, я запускаю for петля.

Перед тем, как начать, мы создаем модель с английским языком в качестве ссылки ( см. Эту ссылку для получения дополнительной информации):

library(udpipe)
ud_model <- udpipe_download_model(language = "english")
ud_model <- udpipe_load_model(ud_model$file_model)

В идеале, мой конечный результат - это кадр данных с 8 столбцами и таким количеством строк, сколько ключевых слов было извлечено.

Я попробовал два метода:

Способ 1: использование dplyr

library(dplyr)
keywords <- list()
for(i in ncol(keywords_en_t)){
  keywords[[i]] <- keywords_en_t %>%
    udpipe_annotate(ud_model,s)
    as.data.frame()
}

Способ 2:

key <- list()
stats <- list()
for(i in ncol(keywords_en_t)){
    key[[i]] <- as.data.frame(udpipe_annotate(ud_model, x = keywords_en_t[,i]))
    stats[[i]] <- subset(key[[i]], upos %in% "NOUN")
    stats <- txt_freq(x = stats$lemma)
}

Выход

В обоих случаях либо я получаю некоторые ошибки, либо вывод не ожидаемый.

Как уже было сказано, я ожидаю, что на выходе будет фрейм данных с 8 столбцами, представляющими в строках ключевые слова.

Любая идея?

1 ответ

Решение

К сожалению, ваш код содержит много ошибок. Ваши циклы не идут от 1 до количества столбцов, а начинаются только с 8. Либо используйте 1:ncol или же seq_along, Ваши ключевые данные - это матрица, а не data.frame. Вам нужно поставить udpipe_annotate символьный вектор. Если вы просто предоставляете ключ [, 8], вы также предоставляете dimnames для udpipe_annotate, Это может генерировать ключевые слова, которые вам не нужны. В методе 1 вы используете udpipe_annotate(ud_model,s), но нет s определены. В методе 2 вы используете stats[[i]], и сразу после слов вы перезаписываете его, используя stats.

Чтобы исправить некоторые вещи, сначала я преобразовал данные в data.frame. Затем я запускаю цикл, чтобы создать список векторов, содержащих ключевые слова. После этого я создал data.frame из ключевых слов. Эта часть кода учитывает разные длины векторов.

Возможно, вы захотите проверить, как вы получаете свои данные, потому что более логично / аккуратно иметь три столбца ("Заголовок", "Краткое описание", "Язык") и множество строк.

Код

# Transform key into a data.frame. Now it is a matrix. 
key <- as.data.frame(key, stringsAsFactors = FALSE)

library(udpipe)
# prevent downloading ud model if it already exists in the working directory
ud_model <- udpipe_download_model(language = "english", overwrite = FALSE)
ud_model <- udpipe_load_model(ud_model$file_model)

# prepare list with correct length
keywords <- vector(mode = "list", length = ncol(key))

for(i in 1:ncol(key)){
  temp <- as.data.frame(udpipe_annotate(ud_model, x = key[, i]))
  keywords[[i]] <- temp$lemma[temp$upos == "NOUN"]
}

#transform list of vectors to data.frame. 
# Use sapply because vectors are of different lengths.
keywords <- as.data.frame(sapply(keywords, '[', seq(max(lengths(keywords)))), stringsAsFactors = FALSE)

keywords

        V1        V2         V3     V4       V5       V6     V7      V8
1    skill beginners  beginners   logo learning       2d Design     web
2      map    design      guide  award    curve  Texture format  design
3 software    Vector experience   logo  program    guide   <NA>  design
4     <NA>  graphics       <NA> design   design  texture   <NA> website
5     <NA>    vector       <NA>   <NA>   course inkscape   <NA>    tool
6     <NA>   graphic       <NA>   <NA>     <NA>     <NA>   <NA>    <NA>
Другие вопросы по тегам