【问题标题】:Processing JSON using rjson使用 rjson 处理 JSON
【发布时间】:2013-07-14 12:29:45
【问题描述】:

我正在尝试处理一些 JSON 格式的数据。 rjson::fromJSON 成功导入数据并将其放入一个相当笨重的列表中。

library(rjson)
y <- fromJSON(file="http://api.lmiforall.org.uk/api/v1/wf/predict/breakdown/region?soc=6145&minYear=2014&maxYear=2020")
str(y)
List of 3
 $ soc                : num 6145
 $ breakdown          : chr "region"
 $ predictedEmployment:List of 7
  ..$ :List of 2
  .. ..$ year     : num 2014
  .. ..$ breakdown:List of 12
  .. .. ..$ :List of 3
  .. .. .. ..$ code      : num 1
  .. .. .. ..$ name      : chr "London"
  .. .. .. ..$ employment: num 74910
  .. .. ..$ :List of 3
  .. .. .. ..$ code      : num 7
  .. .. .. ..$ name      : chr "Yorkshire and the Humber"
  .. .. .. ..$ employment: num 61132
  ...

但是,由于这本质上是表格数据,因此我希望使用简洁的data.frame。经过多次试验和错误,我得到了结果:

y.p <- do.call(rbind,lapply(y[[3]], function(p) cbind(p$year,do.call(rbind,lapply(p$breakdown, function(q) data.frame(q$name,q$employment,stringsAsFactors=F))))))
head(y.p)
  p$year                   q.name q.employment
1   2014                   London     74909.59
2   2014 Yorkshire and the Humber     61131.62
3   2014     South West (England)     65833.57
4   2014                    Wales     33002.64
5   2014  West Midlands (England)     68695.34
6   2014     South East (England)     98407.36

但该命令似乎过于繁琐和复杂。有没有更简单的方法?

【问题讨论】:

    标签: json r rjson


    【解决方案1】:

    这里我恢复了列表的几何形状

    ni <- seq_along(y[[3]])
    nj <- seq_along(y[[c(3, 1, 2)]])
    nij <- as.matrix(expand.grid(3, ni=ni, 2, nj=nj))
    

    然后使用nij的行作为嵌套列表的索引提取相关变量信息

    data <- apply(nij, 1, function(ij) y[[ij]])
    year <- apply(cbind(nij[,1:2], 1), 1, function(ij) y[[ij]])
    

    并使其成为更友好的结构

    > data.frame(year, do.call(rbind, data))
       year code                     name employment
    1  2014    1                   London   74909.59
    2  2015    5  West Midlands (England)   69132.34
    3  2016   12         Northern Ireland   24313.94
    4  2017    5  West Midlands (England)    71723.4
    5  2018    9     North East (England)   27199.99
    6  2019    4     South West (England)   71219.51
    

    【讨论】:

    【解决方案2】:

    我不确定它是否更简单,但结果更完整,我认为更容易阅读。我使用Map 的想法是,对于每一对(年份、细分),将细分数据汇总到单个表中,然后将其与年份结合起来。

    dat <- y[[3]]
    res <- Map(function(x,y)data.frame(year=y,
                                       do.call(rbind,lapply(x,as.data.frame))),
            lapply(dat,'[[','breakdown'),
            lapply(dat,'[[','year'))
    ## transform the list to a big data.frame
    do.call(rbind,res)
       year code                     name employment
    1  2014    1                   London   74909.59
    2  2014    7 Yorkshire and the Humber   61131.62
    3  2014    4     South West (England)   65833.57
    4  2014   10                    Wales   33002.64
    5  2014    5  West Midlands (England)   68695.34
    6  2014    2     South East (England)   98407.36
    

    【讨论】:

    • 我已经接受了这个答案,因为它更容易阅读正在发生的事情。
    • 当我运行这个时,例如,lapply(dat, "[[", "breakdown")dat = y 我得到 Error in FUN(X[[1L]], ...) : subscript out of bounds ??
    • @MartinMorgan 很好。我编辑我的答案。我忘了提dat &lt;- y[[3]]
    • @agstudy 感谢您的出色回答!请问,我从来没有见过你在这里使用的 lapply。你能解释一下发生了什么吗?我习惯了 lapply 的形式:lapply(, ),但您似乎正在提取对象的某些部分。这是如何运作的?对象 dat 甚至没有最高级别的“细分”或“年份”。我似乎在文档中找不到任何东西来解释这个用例。非常感谢!!
    • @MikeWilliamson 你可以看到?lapplylapply(X, FUN, ...) 其中...optional arguments to FUN。所以这里我的 FUN 是 [[,我将列名(细分或年份)作为可选参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 2021-12-30
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 2023-03-06
    相关资源
    最近更新 更多