从列表中的列表中提取JSON分析的变量

时间:2019-02-09 14:36:58

标签: r

作为论文的一部分,我正在分析各政党的极性。在收到带有JSON形式的Facebook消息的数据转储后,我将其解析为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]

编辑: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$scoresentiment$score之间的区别。

我也尝试过

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

不幸的是,这不能处理NULL项(即$sentiment为空而$polarity不为空)。因此,它创建了一个有缺陷的矩阵。

我也玩过flattenunlisttranpose函数,但这似乎无济于事。我没有R方面的经验,因此我希望有人可以帮助我提取正确的分数并将其作为数据框的一栏输入。我希望我提供了所有必要的信息。

2 个答案:

答案 0 :(得分:0)

第一部分代码是我创建一个示例。我通过设置score = c()来设置NULL值是否可以解决您的问题。我确实必须使用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
    }
}

请注意,send.pol.score将是数据集的长度,如果值为NULL,则将等于0。我不知道这些值可以采用什么值,但您可能需要将其更改为sent.pol.score <- rep(NA, length(df$sentiment))

答案 1 :(得分:0)

在Rex的帮助下,我发现list()中存在一些空列表(以$sentiment的形式)。结合Rex的建议,使我想到了以下解决方案:

#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: https://stackoverflow.com/questions/7942519/deleting-every-n-th-row-in-a-dataframe

#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中形成了一个连贯的列。