Извлечь JSON-проанализированную переменную из списка в списке - PullRequest
0 голосов
/ 09 февраля 2019

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

Мне нужно извлечь $sentiment$polarity$score из списка в списке внутри списка.

Observations: 63,465
Variables: 5
$ description <chr> "'TEXT'" ...
$ parties     <list> ["X", "X", "Y", ...
$ date        <date> 2018-03-05, 2018-03-05...
$ title       <chr> NA, NA...
$ sentiment   <list> [[[0.2998967, "Positief"], ...

Использование glimpse(df$sentiment) показывает:

 $ :List of 2
  ..$ polarity    :List of 2
  .. ..$ score      : num 0.15
  .. ..$ description: chr "Neutraal"
  ..$ subjectivity:List of 2
  .. ..$ score      : num 0.65
  .. ..$ description: chr "Erg subjectief"
  [list output truncated]

EDIT: head (df $ sentiment, n = 1) дает:

[[1]]
[[1]]$`polarity`
[[1]]$`polarity`$`score`
[1] 0.2998967

[[1]]$`polarity`$description
[1] "Positief"

[[1]]$subjectivity
[[1]]$subjectivity$`score`
[1] 0.5458678

[[1]]$subjectivity$description
[1] "Subjectief"

Но,Проблемная часть df$sentiment существует в (при запуске head(df$sentiment, n=10)) следующим образом:

[[5]]
named list()

Таким образом, наблюдение содержит пустой список, а не формат, содержащий два других списка.

Я пробовал следующее:

df %>% unnest(sentiment, .drop = FALSE, .sep = '"')

К сожалению, это удвоило мою df, потеряв при этом разницу между polarity$score и sentiment$score.

Также я попытался

matrix(unlist(df$sentiment),ncol=4,byrow=TRUE)

К сожалению, это не может справиться с пустыми значениями (т. Е. Когда $sentiment пусто, а $polarity не пусто).Таким образом, он создает некорректную матрицу.

Я также поиграл с функциями flatten, unlist и tranpose, но это, похоже, никуда меня не привело.Я не настолько опытен в R, поэтому я надеялся, что кто-нибудь может помочь мне выбрать правильную оценку и ввести ее в качестве столбца для моего информационного кадра.Я надеюсь, что предоставил всю необходимую информацию.

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

После помощи Рекса я обнаружил существование некоторых пустых списков (в форме list()) внутри $sentiment.Это, в сочетании с рекомендациями Рекса, привело меня к следующему решению:

#Remove empty lists from $sentiment
df.1 <- df %>% filter(sentiment != "list()")

#Unnest $sentiment list
df.2 <- df.1 %>% unnest(sentiment, .drop = FALSE, .sep = '"')

#Create function to remove even rows in df.2,  which contain $sentiment$subjectivity
Nth.delete <-function(dataframe, n)dataframe[-(seq(n,to=nrow(dataframe),by=n)),]

See: /5918073/udalenie-kazhdoi-n-i-stroki-v-kadre-dannyh

#Execute Nth.delete function on every even rows of df, containing $sentiment$subjectivity
df.3 <- Nth.delete(df.1, 2)

#Unnest list $sentiment again to disctinct between $polarity$score and $polarity$description
df.4 <- df.3 %>% unnest(sentiment, .drop = FALSE, .sep = '"')

#Execute Nth.delete function again to remove the even rows containing $sentiment$polarity$description
df.5 <- Nth.delete(df.4, 2)

Это создало df, в котором $sentiment$polarity$score формирует связную колонку в моем df.

0 голосов
/ 09 февраля 2019

Первый бит кода - это я создаю пример.Я сделал значение NULL, установив score = c(), чтобы посмотреть, решит ли это вашу проблему.Я должен был сделать это с помощью цикла for, но он должен работать.Второй бит - это то, как вы будете кодировать его, используя фрейм данных и список значений.Он в основном выполняет промежуточную проверку для проверки списков NULL.

##construction of example data frame
a <- list(polarity = list(score = c(), description = "positief"))
b <- list(subjectivity = list(score = 2, description = "subjectief"))
c <- list(empty_list = list())
d <- list(c(a, b, c))

##my d is equivalent to your df
d[[1]][[1]][[1]]
length(d)
sent.pol.score <- double(length(d))
for ( i in 1 : length(d) ) {
    if ( length(d[[1]][[1]][[1]]) == 1 ) {
        sent.pol.score[i] <- d[[1]][[1]][[1]]
    }
}


##this should work with your data frame
sent.pol.score <- double(length(df$sentiment))
for ( i in 1 : length(df$sentiment) ) {
    if ( length(df$sentiment$polarity$score) == 1 ) {
        sent.pol.score[i] <- df$sentiment$polarity$score
    }
}

Обратите внимание, что sent.pol.score будет длиной набора данных и будет равен 0, если значение равно NULL.Я не знаю, какие значения они могут принять, но вы можете изменить его на sent.pol.score <- rep(NA, length(df$sentiment)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...