【问题标题】:How to import JSON into R and convert it to table?如何将 JSON 导入 R 并将其转换为表格?
【发布时间】:2014-01-22 09:53:37
【问题描述】:

我想使用现在以 JSON 格式保存的数据。但我对 R 很陌生,对如何处理数据一无所知。您可以在下面看到我设法实现的目标。但首先,我的代码:

library(rjson)
json_file <- "C:\\Users\\Saonkfas\\Desktop\\WOWPAPI\\wowpfinaljson.json"
json_data <- fromJSON(paste(readLines(json_file), collapse=""))

我能够得到数据:

for (x in json_data){print (x)}

虽然输出看起来很原始:

[[1]]
[[1]]$wins
[1] "118"

[[1]]$losses
[1] "40"
# And so on

请注意,JSON 有点嵌套。我可以用 Python 创建表,但 R 似乎要复杂得多。

编辑:

我的 JSON:

{
"play1": [
    {
        "wins": "118",
        "losses": "40",
        "max_killed": "7",
        "battles": "158",
        "plane_id": "4401",
        "max_ground_object_destroyed": "3"
    },
    {
        "wins": "100",
        "losses": "58",
        "max_killed": "7",
        "battles": "158",
        "plane_id": "2401",
        "max_ground_object_destroyed": "3"
    },
    {
        "wins": "120",
        "losses": "38",
        "max_killed": "7",
        "battles": "158",
        "plane_id": "2403",
        "max_ground_object_destroyed": "3"
    }
],

"play2": [
    {
        "wins": "12",
        "losses": "450",
        "max_killed": "7",
        "battles": "158",
        "plane_id": "4401",
        "max_ground_object_destroyed": "3"
    },
    {
        "wins": "150",
        "losses": "8",
        "max_killed": "7",
        "battles": "158",
        "plane_id": "2401",
        "max_ground_object_destroyed": "3"
    },
    {
        "wins": "120",
        "losses": "328",
        "max_killed": "7",
        "battles": "158",
        "plane_id": "2403",
        "max_ground_object_destroyed": "3"
    }
],

【问题讨论】:

标签: json r loops dictionary rjson


【解决方案1】:

fromJSON 返回一个列表,您可以使用*apply 函数遍历每个元素。 将其转换为“表格”(数据框是正确的 R 术语)相当简单(一旦您知道该怎么做!)。

library(rjson)

# You can pass directly the filename
my.JSON <- fromJSON(file="test.json")

df <- lapply(my.JSON, function(play) # Loop through each "play"
  {
  # Convert each group to a data frame.
  # This assumes you have 6 elements each time
  data.frame(matrix(unlist(play), ncol=6, byrow=T))
  })

# Now you have a list of data frames, connect them together in
# one single dataframe
df <- do.call(rbind, df)

# Make column names nicer, remove row names
colnames(df) <- names(my.JSON[[1]][[1]])
rownames(df) <- NULL

df
  wins losses max_killed battles plane_id max_ground_object_destroyed
1  118     40          7     158     4401                           3
2  100     58          7     158     2401                           3
3  120     38          7     158     2403                           3
4   12    450          7     158     4401                           3
5  150      8          7     158     2401                           3
6  120    328          7     158     2403                           3

【讨论】:

    【解决方案2】:

    我发现jsonlite 对这项任务更加用户友好。 Here is a comparison of three JSON parsing packages(偏向于jsonlite

    library(jsonlite)
    data <- fromJSON('path/to/file.json')
    
    data
    #> $play1
    #   wins losses max_killed battles plane_id max_ground_object_destroyed
    # 1  118     40          7     158     4401                           3
    # 2  100     58          7     158     2401                           3
    # 3  120     38          7     158     2403                           3
    # 
    # $play2
    #   wins losses max_killed battles plane_id max_ground_object_destroyed
    # 1   12    450          7     158     4401                           3
    # 2  150      8          7     158     2401                           3
    # 3  120    328          7     158     2403                           3
    

    如果您想将这些列表名称折叠到一个新列中,我推荐dplyr::bind_rows 而不是do.call(rbind, data)

    library(dplyr)
    data <- bind_rows(data, .id = 'play')
    
    # Source: local data frame [6 x 7]
    
    #    play  wins losses max_killed battles plane_id max_ground_object_destroyed
    #   (chr) (chr)  (chr)      (chr)   (chr)    (chr)                       (chr)
    # 1 play1   118     40          7     158     4401                           3
    # 2 play1   100     58          7     158     2401                           3
    # 3 play1   120     38          7     158     2403                           3
    # 4 play2    12    450          7     158     4401                           3
    # 5 play2   150      8          7     158     2401                           3
    # 6 play2   120    328          7     158     2403                           3
    

    请注意,列可能不是您期望的类型(请注意,列都是字符,因为所有数字都在提供的 JSON 数据中引用)!

    2017 年 11 月编辑:类型转换的一种方法是使用 mutate_if 猜测字符列的预期类型。

    data <- mutate_if(data, is.character, type.convert, as.is = TRUE)
    

    【讨论】:

    • 您可以使用来自jsonliterbind.pages 而不是加载reshape2,它可以与fromJSON 进行一次通话
    • @RichardScriven 整洁!我没有注意到这个功能。尽管在这种情况下,它的作用类似于do.call(rbind, data),因为它不会将 play# 保留为新变量(如果这对 OP 很重要)
    • @Eric 获取正确列类型的最佳方法是什么?如果我将 json 文件转换为 csv 并导入到 R,我会得到正确的类型,但直接使用 jsonlite 导入会给我错误的类型。
    • @ant 很遗憾,如果不知道您的数据是什么样的以及哪些类型是错误的,我无法回答您的问题。不过,最简单的方法可能是将所有内容都转换为数据框,然后在必要时将列强制转换为所需的类型。
    【解决方案3】:

    我更喜欢 tidyjson 而不是 rjson 和 jsonlite,因为它具有将多级嵌套 json 对象转换为二维表的简单工作流程。使用来自 github 的这个包可以轻松解决您的问题。

    devtools::install_github("sailthru/tidyjson")
    
    library(tidyjson)
    library(dplyr)
    
    > json %>%  as.tbl_json %>% gather_keys %>% gather_array %>%  
    +   spread_values(
    +     wins = jstring("wins"),
    +     losses = jstring("losses"),
    +     max_killed = jstring("max_killed"),
    +     battles = jstring("battles"),
    +     plane_id = jstring("plane_id"),
    +     max_ground_object_destroyed = jstring("max_ground_object_destroyed")
    +    )
    

    输出

      document.id   key array.index wins losses max_killed battles plane_id max_ground_object_destroyed
    1           1 play1           1  118     40          7     158     4401                           3
    2           1 play1           2  100     58          7     158     2401                           3
    3           1 play1           3  120     38          7     158     2403                           3
    4           1 play2           1   12    450          7     158     4401                           3
    5           1 play2           2  150      8          7     158     2401                           3
    6           1 play2           3  120    328          7     158     2403                           3
    

    【讨论】:

    • 变量json在你的代码中是如何定义的?在其他示例中,这是从磁盘加载的。
    猜你喜欢
    • 1970-01-01
    • 2019-05-16
    • 2020-01-02
    • 2017-04-14
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 2019-12-16
    相关资源
    最近更新 更多