【问题标题】:Trouble using jsonlite's fromJSON() with URL in R在 R 中使用带有 URL 的 jsonlite 的 fromJSON() 出现问题
【发布时间】:2018-03-08 13:13:17
【问题描述】:

我有一个 URL,它以 JSON 格式显示来自某个网​​站的 API 的内容(文件 ID)。 为了以编程方式执行此操作,我使用 jsonlite 包的 fromJSON(txt) 函数,然后将 JSON 解析为向量(或列表,不确定)。

这在我的家用电脑上完美运行。但是,当我在工作中运行相同的代码时,似乎 fromJSON(txt) 无法识别 URL,而是尝试解析实际的 URL 文本,因为我收到以下错误:

 Error: lexical error: invalid char in json text.
                                       https://api.gdc.cancer.gov/file
                     (right here) ------^

我已经多次检查并重新检查了我的代码和 URL。该 URL 在粘贴到浏览器时可以完美运行并返回 JSON 格式的文本。

我尝试了几种替代方案,例如 jsonlite 包的 unserializeJSON() 和 RJSONIO 包的 fromJSON(),后者产生不同的错误。

如果能帮助我找出问题所在,我将不胜感激......

这是我的代码的相关部分:

# The URL (works fine in a browser):
urlForIDs <- "https://api.gdc.cancer.gov/files?filters=%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%0A%20%20%20%20%22op%22%3A%20%22and%22%2C%0A%20%20%20%20%22content%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22op%22%3A%20%22in%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22content%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22field%22%3A%20%22cases.project.program.name%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22value%22%3A%20%22TCGA%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22op%22%3A%20%22and%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22content%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22op%22%3A%20%22in%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22content%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22field%22%3A%20%22cases.project.disease_type%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22value%22%3A%20%22%2ACarcinoma%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22op%22%3A%20%22in%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22content%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22field%22%3A%20%22cases.project.primary_site%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22value%22%3A%20%22Breast%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%0A%7D%0A%2C%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22type%22%2C%22value%22%3A%22copy_number_segment%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22data_category%22%2C%22value%22%3A%22Copy%20Number%20Variation%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22data_type%22%2C%22value%22%3A%22Masked%20Copy%20Number%20Segment%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22experimental_strategy%22%2C%22value%22%3A%22Genotyping%20Array%22%7D%7D%5D%7D%5D%7D&fields=file_id&size=5000&related_files=false"

# Another URL which I tried, that does the same thing, but when creating this one I minimised the JSON (removed white spaces) before encoding it:
# The first one worked on Chrome browser but not in Explorer, this one does work in Explorer, but not in the fromJSON() function:
url2 <- "https://api.gdc.cancer.gov/files?filters=%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22cases.project.program.name%22%2C%22value%22%3A%22TCGA%22%7D%7D%2C%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22cases.project.disease_type%22%2C%22value%22%3A%22%2ACarcinoma%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22cases.project.primary_site%22%2C%22value%22%3A%22Breast%22%7D%7D%5D%7D%5D%7D%2C%7B%22op%22%3A%22and%22%2C%22content%22%3A%5B%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22type%22%2C%22value%22%3A%22copy_number_segment%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22data_category%22%2C%22value%22%3A%22Copy%20Number%20Variation%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22data_type%22%2C%22value%22%3A%22Masked%20Copy%20Number%20Segment%22%7D%7D%2C%7B%22op%22%3A%22in%22%2C%22content%22%3A%7B%22field%22%3A%22experimental_strategy%22%2C%22value%22%3A%22Genotyping%20Array%22%7D%7D%5D%7D%5D%7D&fields=file_id&size=5000&related_files=false"

fileIDs <- fromJSON(urlForIDs) # I have tried changing parameters, such as 'simplifyVector = FALSE' but nothing seems to work.

# The following line is not executed, since the error happens before
fileIDs$data$hits$file_id

也许最奇怪的是,复制和粘贴的相同代码在我的家用电脑上运行良好。

提前致谢。

更新: 尝试调试问题,我发现问题是当到达jsonlite包中的以下函数时,它似乎检查是否有URL,否则将其视为JSON文本。由于某种原因,它进入了“else”部分......这是函数:

function (txt, bigint_as_char = FALSE) 
{
    if (inherits(txt, "connection")) {
        parse_con(txt, bigint_as_char)
    }
    else {
        parse_string(txt, bigint_as_char)
    }
}

更新 #2: 我意识到,当我将链接粘贴到 Microsoft Edge 或 Internet Explorer 时,一些 URL 被截断,然后我收到一条消息,指出它不是有效的 JSON。我更改了默认设置以使用 Chrome 作为默认浏览器,因为 Chrome 不会将其关闭。但它仍然不起作用...... 这可能是问题吗? 有什么建议吗?

最终更新: 我写信给包的创建者 Jeroen Ooms,他建议我从 GitHub 下载包,因为问题已经解决了。 这是一年多以前的事了,所以我想现在从 CRAN 下载包时也没有这个问题。 感谢所有回复的人!

【问题讨论】:

  • 它进入了 'else' 部分,因为 txt 不是 connection 对象,所以它在那个实例中做正确的事情
  • @SymbolixAU 这正是问题所在……它是一个URL,jsonlite的fromJSON()函数可以获取一个URL并使用它来检索数据,然后读取URL返回的JSON。但是由于某种原因,在我的工作计算机上,它并没有识别出 URL,而是尝试将其作为 JSON 读取,而不是使用它来检索数据,然后将该数据作为 JSON 读取,因此出现错误。我试图弄清楚我需要在我的工作计算机上更改哪些互联网设置才能让它像在我的 PC 上一样工作。有没有办法自动启用更长的网址?
  • 我看到了在防火墙后面使用jsonlite 的问题 - 贵公司是否使用防火墙,因为这可能是问题的根源?

标签: json r url jsonlite


【解决方案1】:

您可以使用readLines 直接从URL 读取文本,手动为其分配一个“json”类,然后使用jsonlite 转换为R 对象。

注意:您会收到一些关于行尾不完整的警告

res <- readLines(urlForIDs)
res2 <- readLines(url2)

class(res) <- "json"
class(res2) <- "json"

## View the raw JSON
jsonlite::prettify(res)
jsonlite::prettify(res2)

## convert to data.frame
df <- jsonlite::fromJSON(res)
df2 <- jsonlite::fromJSON(res2)

str(df)
# List of 2
# $ data    :List of 2
# ..$ hits      :'data.frame':  2223 obs. of  2 variables:
#   .. ..$ file_id: chr [1:2223] "2f22c96a-7b69-4e9c-96ac-be58fc2a79f1" "38d7d00a-594d-4bdc-a34c-660bfc195ff0" "03596a48-d4d1-4d8e-b76b-75fe8c0f0b75" "6bfe38b2-f0bb-4a79-83fd-b0c18c0f6a79" ...
# .. ..$ id     : chr [1:2223] "2f22c96a-7b69-4e9c-96ac-be58fc2a79f1" "38d7d00a-594d-4bdc-a34c-660bfc195ff0" "03596a48-d4d1-4d8e-b76b-75fe8c0f0b75" "6bfe38b2-f0bb-4a79-83fd-b0c18c0f6a79" ...
# ..$ pagination:List of 7
# .. ..$ count: int 2223
# .. ..$ sort : chr ""
# .. ..$ from : int 0
# .. ..$ page : int 1
# .. ..$ total: int 2223
# .. ..$ pages: int 1
# .. ..$ size : int 5000
# $ warnings: Named list()


str(df2)
# List of 2
# $ data    :List of 2
# ..$ hits      :'data.frame':  2223 obs. of  2 variables:
#   .. ..$ file_id: chr [1:2223] "2f22c96a-7b69-4e9c-96ac-be58fc2a79f1" "38d7d00a-594d-4bdc-a34c-660bfc195ff0" "03596a48-d4d1-4d8e-b76b-75fe8c0f0b75" "6bfe38b2-f0bb-4a79-83fd-b0c18c0f6a79" ...
# .. ..$ id     : chr [1:2223] "2f22c96a-7b69-4e9c-96ac-be58fc2a79f1" "38d7d00a-594d-4bdc-a34c-660bfc195ff0" "03596a48-d4d1-4d8e-b76b-75fe8c0f0b75" "6bfe38b2-f0bb-4a79-83fd-b0c18c0f6a79" ...
# ..$ pagination:List of 7
# .. ..$ count: int 2223
# .. ..$ sort : chr ""
# .. ..$ from : int 0
# .. ..$ page : int 1
# .. ..$ total: int 2223
# .. ..$ pages: int 1
# .. ..$ size : int 5000
# $ warnings: Named list()

另外,请注意length of the URL

【讨论】:

  • 谢谢!但重点是 fromJSON() 函数旨在能够识别 URL,使用它来检索数据,然后从 URL 返回的 JSON 中读取。它在我的 PC 上运行良好,但由于某种原因,在工作计算机上它无法识别 URL,因此将其视为文本,在这种情况下,它会尝试像 JSON 一样读取它,然后抛出错误,因为它无法像解析 JSON 一样解析 URL。我认为你是对的,它与 URL 的长度有关,但在我的电脑上它可以工作,我无法弄清楚要更改哪些设置来排除这个限制
  • 这是一个很常见的问题。可能的原因是当网页没有返回有效的 json 时 fromJSON() 会恢复为尝试将输入读取为字符串。
【解决方案2】:

问题已修复(一年前,但分享以防万一它帮助其他人)。

我写信给该软件包的创建者 Jeroen Ooms,他建议我从 GitHub 下载该软件包,因为那里已经解决了问题。 这是一年多以前的事了,所以我想现在标准包从 CRAN 下载时也没有这个问题。

从 GitHub 下载:

devtools::install_github("jeroen/jsonlite")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多