如何将这个嵌套的重复 json 对象解码为数据帧

How to decode this nested repeated json object to dataframe

我正在尝试将重复的 json 对象解码为 R 中的数据帧。我能够解码第一部分,但对象在重复显示下一列的信息(最好是你见代码)

预计:

数据集

structure(list(X__1 = c(1, 2, 3, 4, 5), country = c(3, 3, 3, 
3, 3), message = c("<p>Con la tua firma, ripartiamo insieme. <br> In sede di dichiarazione dei redditi dona il <a class=\"_58cn\"><span class=\"_5afx\"><span class=\"_58cl _5afz\">#</span><span class=\"_58cm\">2x1000</span></span></a> al <a class=\"_58cn\"><span class=\"_5afx\"><span class=\"_58cl _5afz\">#</span><span class=\"_58cm\">PD</span></span></a>, scrivi <a class=\"_58cn\"><span class=\"_5afx\"><span class=\"_58cl _5afz\">#</span><span class=\"_58cm\">M20</span></span></a>.<br> A te non costa nulla, insieme saremo più liberi.</p>", 
"<p>Con la tua firma, ripartiamo insieme</p>", "<p>Lâ01apprendimento permanente è la più grande possibilità  per garantire un lavoro stabile durante la tua carriera. Ã0 un tuo diritto formarti per il tuo (prossimo) lavoro. Noi vogliamo una garanzia per le competenze europea. Vogliamo un pilastro europeo dei diritti sociali. Vogliamo anche un piano europeo di azione sociale. <a class=\"_58cn\"><span class=\"_5afx\"><span class=\"_58cl _5afz\">#</span><span class=\"_58cm\">SocialSummit17</span></span></a> <a class=\"_58cn\"><span class=\"_5afx\"><span class=\"_58cl _5afz\">#</span><span class=\"_58cm\">SocialEurope</span></span></a> <a class=\"_58cn\"><span class=\"_5afx\"><span class=\"_58cl _5afz\">#</span><span class=\"_58cm\">Gothenburg</span></span></a></p>", 
"<p>Che brutta giornata per lâ01Italia e per la Democrazia.<br> Era tutto pronto, anche io ero pronto a occuparmi di immigrazione e sicurezza, ma niente, qualcuno oggi ha detto NO.<br> Il governo del cambiamento non poteva nascere, i Signori dello Spread e delle banche, i ministri di Berlino, di Parigi e di Bruxelles non erano dâ01accordo.<br> Rabbia? Tanta. Paura? Zero.<br> Cambieremo questo Paese, insieme.<span class=\"text_exposed_hide\">...</span><span class=\"text_exposed_show\"><br> Io non mollo Amici, conto su di Voi.<br> Prima gli italiani!</span></p>", 
"<div class=\"mbs _5pbx\" id=\"js_5oc\">Cambiamo insieme la Basilicata x un futuro migliore! Segui il nostro lavoro giornoxgiorno!</div>"
), created_at = structure(c(1527751501, 1526307860, 1510831668, 
1527504155, 1526925698), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    updated_at = structure(c(1528033793, 1526892761, 1510831798, 
    1527763853, 1528640033), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    lang = c("it-IT", "it-IT", "it-IT", "it-IT", "it-IT"), political_probability = c(0.996111675473273, 
    0.898237740210695, 0.78140195632652, 0.996097443958498, 0.780792285415908
    ), targets = c("{\"target\": \"Age\", \"segment\": \"compresa tra 35 e 64 anni \"}", 
    "{\"target\": \"Age\", \"segment\": \"compresa tra 25 e 64 anni \"}", 
    NA, "{\"target\": \"Age\", \"segment\": \"pari o superiore a 13 anni \"}", 
    "{\"target\": \"Age\", \"segment\": \"18 and older\"}, {\"target\": \"Region\", \"segment\": \"Basilicata\"}"
    ), advertiser = c("Partito Democratico", "Partito Democratico", 
    "Partito del Socialismo Europeo", "Matteo Salvini", "Gianni Rosa"
    ), id = c(3228, 3229, 3230, 3231, 3232)), row.names = c(NA, 
-5L), class = c("tbl_df", "tbl", "data.frame"))

我的尝试

我尝试读取该文件,然后尝试使用 json精简包

对其进行解码
doc <-read_excel("italy.xlsx")
doc[doc$targets == "NA"] <- NA

flatten_json <- . %>% 
  str_c(., collapse = ",") %>% 
   str_c("[", ., "]") %>% 
  # str_c("{", ., "}") %>% 
   fromJSON(flatten = T)


parse <- . %>% 
  bind_cols(flatten_json(.$targets))

doc <- parse(doc)

我得到的结果是处理第 1 行和第 2 行,因为它们没有嵌套结构,"NA" 和空白行以及第 5 行

等嵌套结构失败

要使数据与当前行保持关联,您需要在 targets 中迭代 fromJSON。不过,您需要故意跳过 NA 值(放入一个可以很好扩展的占位符),并将所有内容包装在 [...] 中,因为第五个观察结果格式不正确 JSON。

之后,您需要进行一些修改才能将其转换为正确的形式。 tidyr::unnest 将扩展列表列,tidyr::spread 将数据重塑为宽格式。

library(tidyverse)

df2 <- df %>% 
    mutate(targets = map(targets, ~if (is.na(.x)) {    # iterate, create list column
            tibble(target = 'Age')    # what to return for NAs
        } else {
            jsonlite::fromJSON(paste0('[', .x, ']'))    # parse fixed JSON
        })) %>% 
    unnest() %>%     # expand list column
    spread(target, segment)    # reshape from long to wide form

df2
#> # A tibble: 5 x 11
#>    X__1 country message created_at          updated_at          lang 
#>   <dbl>   <dbl> <chr>   <dttm>              <dttm>              <chr>
#> 1     1       3 "<p>Co… 2018-05-31 07:25:01 2018-06-03 13:49:53 it-IT
#> 2     2       3 <p>Con… 2018-05-14 14:24:20 2018-05-21 08:52:41 it-IT
#> 3     3       3 "<p>L\… 2017-11-16 11:27:48 2017-11-16 11:29:58 it-IT
#> 4     4       3 "<p>Ch… 2018-05-28 10:42:35 2018-05-31 10:50:53 it-IT
#> 5     5       3 "<div … 2018-05-21 18:01:38 2018-06-10 14:13:53 it-IT
#> # … with 5 more variables: political_probability <dbl>, advertiser <chr>,
#> #   id <dbl>, Age <chr>, Region <chr>

df2 %>% select(id, Age, Region)
#> # A tibble: 5 x 3
#>      id Age                           Region    
#>   <dbl> <chr>                         <chr>     
#> 1  3228 "compresa tra 35 e 64 anni "  <NA>      
#> 2  3229 "compresa tra 25 e 64 anni "  <NA>      
#> 3  3230 <NA>                          <NA>      
#> 4  3231 "pari o superiore a 13 anni " <NA>      
#> 5  3232 18 and older                  Basilicata