web-dev-qa-db-fra.com

Erreur lors de l'analyse du fichier JSON avec le package jsonlite

J'essaie de lire un fichier JSON dans R mais j'ai l'erreur suivante: 

Error in parseJSON(txt) : parse error: trailing garbage
      [ 33.816101, -117.979401 ] } { "a": "Mozilla\/4.0 (compatibl
                 (right here) ------^

J'ai téléchargé le fichier à partir de http://1usagov.measuredvoice.com/ et l'ai décompressé à l'aide de 7Zip, puis j'ai utilisé le code suivant dans R:

library(jsonlite)
jsonData <- fromJSON("usagov_bitly_data2013-05-17-1368832207")

Je ne suis pas sûr de savoir pourquoi cette erreur se produit, j'ai cherché dans Google mais il n'y a aucune information, quelqu'un qui pourrait m'aider? Est-ce un problème de fichier ou mon code?

15
adolfohc

UNE AUTRE MISE À JOUR

Vous pouvez utiliser le package ndjson pour traiter ces données JSON ndjson/streaming. Il est plus rapide que jsonlite::stream_in() et produit toujours un bloc de données complètement «plat»:

system.time(bitly01 <- ndjson::stream_in("usagov_bitly_data2013-05-17-1368832207.gz"))
##    user  system elapsed 
##   0.146   0.004   0.154

system.time(bitly02 <- jsonlite::stream_in(file("usagov_bitly_data2013-05-17-1368832207.gz"), verbose=FALSE, pagesize=10000))
##    user  system elapsed 
##   0.419   0.008   0.427

Si nous examinons le cadre de données résultant2, vous verrez que ndjson développe ll en ll.0 et ll.1 dans lequel vous obtenez une colonne list dans jsonlite que vous devrez traiter plus tard.

ndjson:

dplyr::glimpse(bitly01)
## Observations: 3,959
## Variables: 19
## $ a           <chr> "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; HTC_PN071 Build/JZO54K) AppleWebKit/534.30 ...
## $ al          <chr> "en-US", "en-us", "en-US,en;q=0.5", "en-US", "en", "en-US", "en-US,en;q=0.5", "en-us", "e...
## $ c           <chr> "US", NA, "US", "US", NA, "US", "US", NA, "AU", NA, "US", "US", "US", "US", "US", "US", "...
## $ cy          <chr> "Anaheim", NA, "Fort Huachuca", "Houston", NA, "Mishawaka", "Hammond", NA, "Sydney", NA, ...
## $ g           <chr> "15r91", "ifIpBW", "10DaxOu", "TysVFU", "10IGW7m", "13GrCeP", "YmtpnZ", "13oM0hV", "15r91...
## $ gr          <chr> "CA", NA, "AZ", "TX", NA, "IN", "WI", NA, "02", NA, "OH", "MD", "KY", "OR", "IL", "TX", "...
## $ h           <chr> "10OBm3W", "ifIpBW", "10DaxOt", "TChsoQ", "10IGW7l", "13GrCeP", "YmtpnZ", "15PUeH0", "10O...
## $ hc          <dbl> 1365701422, 1302189369, 1368814585, 1354719206, 1368738258, 1368130510, 1363711958, 13687...
## $ hh          <chr> "j.mp", "1.usa.gov", "1.usa.gov", "1.usa.gov", "1.usa.gov", "1.usa.gov", "1.usa.gov", "go...
## $ l           <chr> "pontifier", "bitly", "jaxstrong", "o_5004fs3lvd", "peacecorps", "bitly", "bitly", "nasat...
## $ ll.0        <dbl> 33.8161, NA, 31.5273, 29.7633, NA, 41.6123, 45.0070, NA, -33.8615, NA, 39.5151, 39.1317, ...
## $ ll.1        <dbl> -117.9794, NA, -110.3607, -95.3633, NA, -86.1381, -92.4591, NA, 151.2055, NA, -84.3983, -...
## $ nk          <dbl> 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ r           <chr> "direct", "http://www.usa.gov/", "http://www.facebook.com/l.php?u=http%3A%2F%2F1.usa.gov%...
## $ t           <dbl> 1368832205, 1368832207, 1368832209, 1368832209, 1368832208, 1368832209, 1368832210, 13688...
## $ tz          <chr> "America/Los_Angeles", "", "America/Phoenix", "America/Chicago", "", "America/Indianapoli...
## $ u           <chr> "http://www.nsa.gov/", "http://answers.usa.gov/system/selfservice.controller?CONFIGURATIO...
## $ _heartbeat_ <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ kw          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...

jsonlite:

dplyr::glimpse(bitly02)
## Observations: 3,959
## Variables: 18
## $ a           <chr> "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; HTC_PN071 Build/JZO54K) AppleWebKit/534.30 ...
## $ c           <chr> "US", NA, "US", "US", NA, "US", "US", NA, "AU", NA, "US", "US", "US", "US", "US", "US", "...
## $ nk          <int> 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ tz          <chr> "America/Los_Angeles", "", "America/Phoenix", "America/Chicago", "", "America/Indianapoli...
## $ gr          <chr> "CA", NA, "AZ", "TX", NA, "IN", "WI", NA, "02", NA, "OH", "MD", "KY", "OR", "IL", "TX", "...
## $ g           <chr> "15r91", "ifIpBW", "10DaxOu", "TysVFU", "10IGW7m", "13GrCeP", "YmtpnZ", "13oM0hV", "15r91...
## $ h           <chr> "10OBm3W", "ifIpBW", "10DaxOt", "TChsoQ", "10IGW7l", "13GrCeP", "YmtpnZ", "15PUeH0", "10O...
## $ l           <chr> "pontifier", "bitly", "jaxstrong", "o_5004fs3lvd", "peacecorps", "bitly", "bitly", "nasat...
## ## $ al          <chr> "en-US", "en-us", "en-US,en;q=0.5", "en-US", "en", "en-US", "en-US,en;q=0.5", "en-us", "e...
## $ hh          <chr> "j.mp", "1.usa.gov", "1.usa.gov", "1.usa.gov", "1.usa.gov", "1.usa.gov", "1.usa.gov", "go...
## $ r           <chr> "direct", "http://www.usa.gov/", "http://www.facebook.com/l.php?u=http%3A%2F%2F1.usa.gov%...
## $ u           <chr> "http://www.nsa.gov/", "http://answers.usa.gov/system/selfservice.controller?CONFIGURATIO...
## $ t           <int> 1368832205, 1368832207, 1368832209, 1368832209, 1368832208, 1368832209, 1368832210, 13688...
## $ hc          <int> 1365701422, 1302189369, 1368814585, 1354719206, 1368738258, 1368130510, 1363711958, 13687...
## $ cy          <chr> "Anaheim", NA, "Fort Huachuca", "Houston", NA, "Mishawaka", "Hammond", NA, "Sydney", NA, ...
## $ ll          <list> [<33.8161, -117.9794>, NULL, <31.5273, -110.3607>, <29.7633, -95.3633>, NULL, <41.6123, ...
## $ _heartbeat_ <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ kw          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...

METTRE &AGRAVE; JOUR

La dernière version du package jsonlite prend en charge le streaming JSON (c'est en réalité ce que c'est). Vous pouvez maintenant le lire avec une ligne comme ceci:

json_file <- stream_in(file("usagov_bitly_data2013-05-17-1368832207"))

Voir également la réponse de Jeroen ci-dessous pour l'analyse de flux directement sur http.


ANCIENNE REPONSE

Il s’agit d’un fichier "pseudo-JSON". Je les rencontre dans de nombreux systèmes d'API naïfs dans lesquels je travaille. Chaque ligne correspond à un code JSON valide, mais les objets individuels ne font pas partie d'un tableau JSON. Vous devez utiliser readLines, puis créer votre propre tableau JSON valide et le transférer dans fromJSON:

library(jsonlite)

# read in individual JSON lines
json_file <- "usagov_bitly_data2013-05-17-1368832207"

# turn it into a proper array by separating each object with a "," and
# wrapping that up in an array with "[]"'s.

dat <- fromJSON(sprintf("[%s]", paste(readLines(json_file), collapse=",")))

dim(dat)

## [1] 3959   18

str(dat)

## 'data.frame': 3959 obs. of  18 variables:
##  $ a          : chr  "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; HTC_PN071 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile "| __truncated__ "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4"| __truncated__ "Mozilla/5.0 (Windows NT 6.1; rv:21.0) Gecko/20100101 Firefox/21.0" "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; SGH-T889 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile S"| __truncated__ ...
##  $ c          : chr  "US" NA "US" "US" ...
##  $ nk         : int  0 0 1 1 0 0 1 0 0 0 ...
##  $ tz         : chr  "America/Los_Angeles" "" "America/Phoenix" "America/Chicago" ...
##  $ gr         : chr  "CA" NA "AZ" "TX" ...
##  $ g          : chr  "15r91" "ifIpBW" "10DaxOu" "TysVFU" ...
##  $ h          : chr  "10OBm3W" "ifIpBW" "10DaxOt" "TChsoQ" ...
##  $ l          : chr  "pontifier" "bitly" "jaxstrong" "o_5004fs3lvd" ...
##  $ al         : chr  "en-US" "en-us" "en-US,en;q=0.5" "en-US" ...
##  $ hh         : chr  "j.mp" "1.usa.gov" "1.usa.gov" "1.usa.gov" ...
## ... (goes on for a while, many columns)

J'ai combiné l'appel readLines avec l'appel paste/sprintf puisque le object.size de l'objet (temporaire) résultant est 2,025,656 octets (~ 2 Mo) et je n'avais pas envie de faire un rm sur une variable temporaire séparée.

38
hrbrmstr

Ce format appelé ndjson et conçu pour importer en continu (y compris le gzip). Il suffit d'utiliser ceci:

con <- url("http://1usagov.measuredvoice.com/bitly_archive/usagov_bitly_data2013-05-17-1368832207.gz")
mydata <- jsonlite::stream_in(gzcon(con))

Vous pouvez également utiliser le paquet curl pour de meilleures performances ou pour personnaliser la requête http:

library(curl)
con <- curl("http://1usagov.measuredvoice.com/bitly_archive/usagov_bitly_data2013-05-17-1368832207.gz")
mydata <- jsonlite::stream_in(gzcon(con))
6
Jeroen

Le package tidyjson peut également lire le format "json lines": read_json("my.json",format="jsonl")

La sortie est ensuite analysée à l'aide d'une série de canaux plutôt que de listes imbriquées avec des cadres de données.

1
Gil Hornung