Аргументы должны иметь одинаковую ошибку длины в R - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь создать хранилище значений ключей, где ключом являются сущности, а значением является средняя оценка настроения сущности в новостных статьях.

У меня есть фрейм данных, содержащий новостные статьи и список сущностей, называемых организациями1, определенных в этих новостных статьях с помощью классификатора. Первая строка списка Organization1 содержит объекты, указанные в статье в первой строке информационного кадра news_us. Я пытаюсь перебрать список организации и создать хранилище значений ключей, ключом которого является имя объекта в списке organization1, а значением - оценка настроения в описании новостей, в котором упоминается объект.

Я могу получить оценки настроения для сущности из статьи, но я хотел сложить их вместе и усреднить оценку настроения.

library(syuzhet)
sentiment <- list()
organization1 <- list(NULL, "US", "Bath", "Animal Crossing", "World Health Organization", 
    NULL, c("Microsoft", "Facebook"))
news_us <- structure(list(title = c("Stocks making the biggest moves after hours: Bed Bath & Beyond, JC Penney, United Airlines and more - CNBC", 
"Los Angeles mayor says 'very difficult to see' large gatherings like concerts and sporting events until 2021 - CNN", 
"Bed Bath & Beyond shares rise as earnings top estimates, retailer plans to maintain some key investments - CNBC", 
"6 weeks with Animal Crossing: New Horizons reveals many frustrations - VentureBeat", 
"Timeline: How Trump And WHO Reacted At Key Moments During The Coronavirus Crisis : Goats and Soda - NPR", 
"Michigan protesters turn out against Whitmer’s strict stay-at-home order - POLITICO"
), description = c("Check out the companies making headlines after the bell.", 
"Los Angeles Mayor Eric Garcetti said Wednesday large gatherings like sporting events or concerts may not resume in the city before 2021 as the US grapples with mitigating the novel coronavirus pandemic.", 
"Bed Bath & Beyond said that its results in 2020 \"will be unfavorably impacted\" by the crisis, and so it will not be offering a first-quarter nor full-year outlook.", 
"Six weeks with Animal Crossing: New Horizons has helped to illuminate some of the game's shortcomings that weren't obvious in our first review.", 
"How did the president respond to key moments during the pandemic? And how did representatives of the World Health Organization respond during the same period?", 
"Many demonstrators, some waving Trump campaign flags, ignored organizers‘ pleas to stay in their cars and flooded the streets of Lansing, the state capital."
), name = c("CNBC", "CNN", "CNBC", "Venturebeat.com", "Npr.org", 
"Politico")), na.action = structure(c(`35` = 35L, `95` = 95L, 
`137` = 137L, `154` = 154L, `213` = 213L, `214` = 214L, `232` = 232L, 
`276` = 276L, `321` = 321L), class = "omit"), row.names = c(NA, 
6L), class = "data.frame")

setNames(lapply(news_us$description, get_sentiment), unlist(organization1))

#$US
#[1] 0

#$Bath
#[1] -0.4

#$`Animal Crossing`
#[1] -0.1

#$`World Health Organization`
#[1] 1.1

#$Microsoft
#[1] -0.6

#$Facebook
#[1] -1.9

tapply(sapply(news_us$description, get_sentiment), unlist(organization1), mean) #this line throws the error

1 Ответ

1 голос
/ 04 мая 2020

Ваша проблема возникает из-за использования «unlist». Избегайте этого, поскольку он отбрасывает значения NULL и объединяет записи списка с несколькими значениями. Ваш список organization1 содержит 7 записей (две из которых имеют значение NULL, а одна - длина = 2). У вас должно быть 6 записей, если это соответствует news_us data.frame - так что там что-то не так c.

Давайте предположим, что первые 6 записей в organization1 верны; Я бы связал их с вашим data.frame, чтобы избежать дальнейших «syn c ошибок»:

news_us$organization1 = organization1[1:6]

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

results = do.call("rbind", apply(news_us, 1, function(item){
    if(!is.null(item$organization1[[1]])) cbind(item$organization1, get_sentiment(item$description))
}))

Этот код удаляет все строки, в которых не было обнаружено organization1 значений. Он также должен дублировать оценки настроения в случае обнаружения более одного organization1. Результаты будут выглядеть примерно так (я считаю, что это ваша цель):

     [,1]                        [,2]  
[1,] "US"                        "-0.4"
[2,] "Bath"                      "-0.1"
[3,] "Animal Crossing"           "1.1" 
[4,] "World Health Organization" "-0.6"

Средние баллы для каждой организации можно затем свернуть, используя by, aggregate или аналогичный.

[Редактировать: Примеры by и aggregate]

by(as.numeric(results[, 2]), results$V1, mean)
aggregate(as.numeric(results[, 2]), list(results$V1), mean)
...