Как декодировать этот вложенный повторяющийся объект json в dataframe - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь декодировать повторяющийся объект 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â\200\231apprendimento permanente è la più grande possibilità  per garantire un lavoro stabile durante la tua carriera. Ã\210 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â\200\231Italia 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â\200\231accordo.<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"))

Моя попытка

Я попытался прочитать файл, затем попытался расшифровать его, используя пакет jsonlite

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

1 Ответ

0 голосов
/ 19 января 2019

Чтобы сохранить данные, связанные с текущими строками, вам нужно будет перебрать fromJSON по targets.Вам нужно будет сознательно пропустить значение 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
...