Ошибка при разборе файла json в R

avatar
Nidhi Garg
7 апреля 2018 в 23:41
113
1
0

Бизнес-данные Yelp со 100 экземплярами в следующем формате:

{ 
    "_id" : ObjectId("5aab338ffc08b46adb7a2320"), 
    "business_id" : "Pd52CjgyEU3Rb8co6QfTPw", 
    "name" : "Flight Deck Bar & Grill", 
    "neighborhood" : "Southeast", 
    "address" : "6730 S Las Vegas Blvd", 
    "city" : "Las Vegas", 
    "state" : "NV", 
    "postal_code" : "89119", 
    "latitude" : 36.0669136, 
    "longitude" : -115.1708484, 
    "stars" : 4.0, 
    "review_count" : NumberInt(13), 
    "is_open" : NumberInt(1), 
    "attributes" : {
        "Alcohol" : "full_bar", 
        "HasTV" : true, 
        "NoiseLevel" : "average", 
        "RestaurantsAttire" : "casual", 
        "BusinessAcceptsCreditCards" : true, 
        "Music" : {
            "dj" : false, 
            "background_music" : true, 
            "no_music" : false, 
            "karaoke" : false, 
            "live" : false, 
            "video" : false, 
            "jukebox" : false
        }, 
        "Ambience" : {
            "romantic" : false, 
            "intimate" : false, 
            "classy" : false, 
            "hipster" : false, 
            "divey" : false, 
            "touristy" : false, 
            "trendy" : false, 
            "upscale" : false, 
            "casual" : true
        }, 
        "RestaurantsGoodForGroups" : true, 
        "Caters" : true, 
        "WiFi" : "free", 
        "RestaurantsReservations" : false, 
        "RestaurantsTableService" : true, 
        "RestaurantsTakeOut" : true, 
        "GoodForKids" : true, 
        "HappyHour" : true, 
        "GoodForDancing" : false, 
        "BikeParking" : true, 
        "OutdoorSeating" : false, 
        "RestaurantsPriceRange2" : NumberInt(2), 
        "RestaurantsDelivery" : false, 
        "BestNights" : {
            "monday" : false, 
            "tuesday" : false, 
            "friday" : false, 
            "wednesday" : true, 
            "thursday" : false, 
            "sunday" : false, 
            "saturday" : false
        }, 
        "GoodForMeal" : {
            "dessert" : false, 
            "latenight" : false, 
            "lunch" : true, 
            "dinner" : false, 
            "breakfast" : false, 
            "brunch" : false
        }, 
        "BusinessParking" : {
            "garage" : false, 
            "street" : false, 
            "validated" : false, 
            "lot" : true, 
            "valet" : false
        }, 
        "CoatCheck" : false, 
        "Smoking" : "no", 
        "WheelchairAccessible" : true
    }, 
    "categories" : [
        "Nightlife", 
        "Bars", 
        "Barbeque", 
        "Sports Bars", 
        "American (New)", 
        "Restaurants"
    ], 
    "hours" : {
        "Monday" : "8:30-22:30", 
        "Tuesday" : "8:30-22:30", 
        "Friday" : "8:30-22:30", 
        "Wednesday" : "8:30-22:30", 
        "Thursday" : "8:30-22:30", 
        "Sunday" : "8:30-22:30", 
        "Saturday" : "8:30-22:30"
    }
}

Мне нужно импортировать это в R. У меня есть следующий код:

library('jsonlite')
data<- stream_in(file("~/Desktop/business100.json"))

Когда я использую приведенный выше код, выдается следующая ошибка:

Error: lexical error: invalid char in json text.
                         {     "_id" : ObjectId("5aab338ffc08b46adb7a2
                     (right here) ------^

Я думаю, что есть какая-то проблема с форматом json, но когда я вижу файл json в mongodb, он выглядит нормально. Что можно для этого сделать, спасибо!

Источник
SymbolixAU
8 апреля 2018 в 01:02
0

Запросите mongodb напрямую, используя mongolite

hrbrmstr
8 апреля 2018 в 01:26
0

Чтобы немного расширить комментарий @SymbolixAU, у вас есть MongoDB расширенный файл JSON, а не правильный файл JSON. (docs.mongodb.com/manual/reference/mongodb-extended-json) Вам нужно будет импортировать его в MongoDB, чтобы использовать его (это самый простой способ) или повторно экспортировать его в строгом режиме.

Ответы (1)

avatar
r2evans
8 апреля 2018 в 04:44
1

Если это mongolite (как предложено в комментариях), это, вероятно, лучший способ. Если вы застряли и не можете использовать его по какой-либо причине, можно заменить эти свойства, отличные от JSON, и проанализировать их с помощью обычных синтаксических анализаторов JSON.

Для обобщения создайте вектор (дословно) строк. Я предполагаю, что каждое свойство имеет форму DiscardableProperty(save_all_here), поэтому хорошей отправной точкой на основе предоставленных вами данных является:

.
ptns <- c('ObjectId', 'NumberInt')
str(jsontxt)
#  chr "{ \n    \"_id\" : ObjectId(\"5aab338ffc08b46adb7a2320\"), \n    \"business_id\" : \"Pd52CjgyEU3Rb8co6QfTPw\", \n    \"name\" : "| __truncated__
jsontxt2 <- Reduce(function(txt, p) gsub(sprintf("%s\\(([^)]+)\\)", p), "\\1", txt),
                   ptns, init=jsontxt)
str(jsontxt2)
#  chr "{ \n    \"_id\" : \"5aab338ffc08b46adb7a2320\", \n    \"business_id\" : \"Pd52CjgyEU3Rb8co6QfTPw\", \n    \"name\" : \"Flight D"| __truncated__

(Обратите внимание на отсутствие ObjectId.)

Это прекрасно анализирует:

str(fromJSON(jsontxt2))
# List of 16
#  $ _id         : chr "5aab338ffc08b46adb7a2320"
#  $ business_id : chr "Pd52CjgyEU3Rb8co6QfTPw"
#  $ name        : chr "Flight Deck Bar & Grill"
#  $ neighborhood: chr "Southeast"
#  $ address     : chr "6730 S Las Vegas Blvd"
# ...

Изменить: однопроходная замена на:

jsontxt2 <- gsub(sprintf("(%s)\\(([^)]+)\\)", paste(ptns, collapse = "|")),
                 "\\2", jsontxt)