2014-10-23 16 views
12

Próbuję odczytać plik JSON do badań, ale mam ten błąd:Błąd parsowania pliku JSON z pakietem jsonlite

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

Pobrałem plik z http://1usagov.measuredvoice.com/ i rozpiął go za pomocą 7zip, następnie użyłem następujący kod w R:

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

nie jestem pewien, dlaczego ten błąd ma miejsce, szukałem w Google ale nie ma informacji, że ktoś może mi pomóc? Czy jest to problem z plikiem lub mój kod?

+0

To jest moja pierwsza praca z plikami JSON, nie mam pewności jak wyglądają, czy może być problem z plikiem JSON? Czy muszę wykonać jakieś wstępne przetwarzanie pliku? Dziękuję za szybką odpowiedź! – adolfohc

Odpowiedz

33

Kolejna aktualizacja

Można użyć pakietu ndjson do przetworzenia tego ndjson/strumieniowe danych JSON. Jest szybszy niż jsonlite::stream_in() i zawsze wywołuje całkowicie ramkę „płaski” Dane:

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 

Jeśli przyjrzymy wynikowy frame2 danych, zobaczysz ndjson rozszerza ll do ll.0 i ll.1 gdzie można dostać kolumnę list w jsonlite że musisz sobie poradzić później.

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... 

UPDATE

Najnowsza wersja pakietu jsonlite obsługuje strumieniowe JSON (co jest, co to jest). Teraz można odczytać go z jednej linii tak:

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

Patrz również odpowiedź Jeroen jest poniżej strumienia-parsowania go bezpośrednio nad http.


OLD ODPOWIEDŹ

Okazuje się, że jest to "pseudo-JSON" plik. Natrafiam na nie w wielu naiwnych systemach API, w których pracuję. Każda linia jest poprawna JSON, ale poszczególne obiekty nie znajdują się w tablicy JSON. Trzeba użyć readLines a następnie zbudować swój własny, poprawny tablicę JSON z niego i przekazać, że do 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) 

I połączył readLines w z wezwaniem paste/sprintf od object.size wypadkowej (tymczasowy) przedmiot to 2,025,656 bajtów (~ 2MB) i nie było ochoty robić rm na osobnej zmiennej tymczasowej.

+1

To rozwiązało problem, nigdy bym nie pomyślał o zrobieniu tego, dzięki! – adolfohc

6

Ten format o nazwie ndjson i przeznaczony do przesyłania strumieniowego (w tym gzip).Wystarczy użyć tego:

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

Lub alternatywnie użyć pakietu curl dla lepszej wydajności lub dostosować żądania http:

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

Pakiet tidyjson można również czytać ten format "linie json": read_json("my.json",format="jsonl")

Dane wyjściowe są następnie analizowane przy użyciu serii potoków, zamiast list zagnieżdżonych w ramkach danych.

Powiązane problemy