【问题标题】:character vector and JSON in RR中的字符向量和JSON
【发布时间】:2018-01-05 05:03:52
【问题描述】:

我使用返回 JSON 响应的 getURLR 调用 API。

当我在 R 中检查 typeof 时,它给了我 [1] "character"

我正在尝试让我的数据保持应有的 JSON 格式,以便能够将其转换为 DataTable。它是字符列表的原因可能是什么?我该如何解决?

这是我从 API 返回的数据中得到的:

[1] "HTTP/1.1 200 OK\r\nDate: Thu, 04 Jan 2018 20:38:50 GMT\r\nContent-Type: application/json; charset=utf-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nSet-Cookie: __cfduid=d6bbf45645c3bd5332f83d25d06d8b8ca1515098329; expires=Fri, 04-Jan-19 20:38:49 GMT; path=/; domain=.onesignal.com; HttpOnly\r\nStatus: 200 OK\r\nCache-Control: public, max-age=7200\r\nAccess-Control-Allow-Origin: *\r\nX-XSS-Protection: 1; mode=block\r\nX-Request-Id: bd2552de-bf7d-4a0c-94d6-ff1b6856002a\r\nAccess-Control-Allow-Headers: SDK-Version\r\nETag: W/\"47580e0a23e806945b01f1237219175c\"\r\nX-Frame-Options: SAMEORIGIN\r\nX-Runtime: 0.112902\r\nX-Content-Type-Options: nosniff\r\nX-Powered-By: Phusion Passenger 5.1.4\r\nCF-Cache-Status: REVALIDATED\r\nExpires: Thu, 04 Jan 2018 22:38:50 GMT\r\nServer: cloudflare-nginx\r\nCF-RAY: 3d8100f109c6a23f-ICN\r\n\r\n{\"total_count\":2057,\"offset\":0,\"limit\":50,\"notifications\":[{\"adm_big_picture\":\"\",\"adm_group\":\"\",\"adm_group_message\":{\"en\":\"\... <truncated>

如果我尝试对这些数据使用 fromJSON 函数, 我明白了:

Error in file(con, "r") : cannot open the connection

【问题讨论】:

  • 文件中的错误(con,“r”):无法打开连接这是我尝试时得到的。尝试使用来自所有 3 个包 jsonlite、RJSONIO 和 rjson 的 fromJSON。从它的样子来看,我需要以某种方式解析我的数据。我不确定是什么方法
  • 我的意思是我尝试了其他软件包,包括 jsonlite。是的,我敢肯定。我正在指定 packagname::fromJSON.
  • 我明白了。看起来字符串不都是 JSON。看起来 JSON 部分从第一个 { 开始。
  • 这是可能的。但是我怎么去那里?
  • sub('^[^\\{]*\\{', '{', x) 之类的东西应该删除直到第一个 { 的所有内容。

标签: r


【解决方案1】:

jsonlite::fromJSON 非常适合解析 JSON。你的问题是你的 JSON 前面有一堆东西。 (也许之后也是,说不出来……)

我认为 JSON 从第一个 { 开始,所以我们将删除之前的所有内容。调用你的数据x:

x = sub('^[^\\{]*\\{', '{', x)
jsonlite::fromJSON(x)

键入未转义的模式into the Regex101 tool 以获得解释。 (未转义的版本使用单反斜杠而不是双反斜杠:^[^\{]*\{。在 R 字符串中,我们需要双反斜杠。)

这是一个基于您的数据的工作示例:

x = 'HTTP/1.1 200 OK
Date: Thu, 04 Jan 2018 20:38:50 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d6bbf45645c3bd5332f83d25d06d8b8ca1515098329; expires=Fri, 04-Jan-19 20:38:49 GMT; path=/; domain=.onesignal.com; HttpOnly
Status: 200 OK
Cache-Control: public, max-age=7200
Access-Control-Allow-Origin: *
X-XSS-Protection: 1; mode=block
X-Request-Id: bd2552de-bf7d-4a0c-94d6-ff1b6856002a
Access-Control-Allow-Headers: SDK-Version
ETag: W/\"47580e0a23e806945b01f1237219175c\"
X-Frame-Options: SAMEORIGIN
X-Runtime: 0.112902
X-Content-Type-Options: nosniff
X-Powered-By: Phusion Passenger 5.1.4
CF-Cache-Status: REVALIDATED\r\nExpires: Thu, 04 Jan 2018 22:38:50 GMT
Server: cloudflare-nginx
CF-RAY: 3d8100f109c6a23f-ICN
{\"total_count\":2057,\"offset\":0,\"limit\":50,\"notifications\":[{\"adm_big_picture\":\"\",\"adm_group\":\"\"}]}'

y = gsub('^[^\\{]*\\{', '{', x)
jsonlite::fromJSON(sub('^(^\\{)*\\{', '{', y))
# $total_count
# [1] 2057
# 
# $offset
# [1] 0
# 
# $limit
# [1] 50
# 
# $notifications
#   adm_big_picture adm_group
# 1                      

【讨论】:

    【解决方案2】:

    您可以使用 rjson 包将您的输入转换为 json。使用simplifyDataFrame 参数fromJSON 应该会输出一个数据框对象。

    Importing data from a JSON file into R

    [编辑]

    您的数据返回了一些标头,您可以克服它,将其从字符串中删除并传递给 fromJSON

    library(stringr)
    library(rjson)
    
    json <- str_sub(str_extract(data, "ICN\\r\\n\\r\\n.*"), 8)
    df <- as.data.frame(fromJSON(json))
    
    > head(df)
       total_count
    1        2057
    

    【讨论】:

    • 文件中的错误(con,“r”):无法打开连接这是我尝试使用时得到的:notificationsDT
    • rjson::fromJSON(paste(readLines(textConnection(notificationsData)) 中的错误:意外字符“H”
    • 您能否在帖子中发布一小部分获取的数据,以了解其无法转换的原因?
    • 确实。请检查。 @Christian Nogueira
    • 您需要对这些数据进行一些处理。它不仅返回 json,还返回 json 在 2 个换行符后开始的标题 \r\n CF-RAY: 3d8100f109c6a23f-ICN\r\n \r\n {\"total_count\":205..跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多