【问题标题】:Parsing JSON string into columns using R - JSON string with inconsistent ordering of properties使用 R 将 JSON 字符串解析为列 - 属性顺序不一致的 JSON 字符串
【发布时间】:2021-06-28 14:46:31
【问题描述】:

我有一个带有 JSON 字符串的 CSV,其中的字段顺序不一致。所以它看起来像这样:

Row 1: '{"name":"John", "age":30, "car":null}'
Row 2: '{"name":"Chuck", "car":black, "age":25}'
Row 3: '{"car":blue, "age":54, "name":"David"}'

我希望使用 R 将其解析为具有适当数据的列。所以我想创建一个“姓名”列、“年龄”列和“汽车”列,并让它们填充适当的数据。无论如何要使用 JSONlite 来执行此操作,还是我需要找出一种方法来从 JSON 字符串中查询属性名称(汽车、姓名、年龄)并使用后续值填充该列?

【问题讨论】:

    标签: r jsonparser


    【解决方案1】:

    您可以使用jsonlite 库,但是为了解析数据,您必须对字符串进行一些“调整”。假设您拥有df,如下所示

    my_df <- data.frame(column_1 = 
      c('{"name":"John", "age":30, "car":null}',
      '{"name":"Chuck", "car":"black", "age":25}',
      '{"car":"blue", "age":54, "name":
      "David"}')
    )
    

    您必须具有有效的json 格式才能正确解析数据。在本例中是array json 格式,因此数据必须有[]。此外,每个元素必须用, 分隔。小心strings,每个都必须有"&lt;string&gt;"。 (您没有在示例中使用 blueblack 数据添加它)

    考虑到这一点,我们现在可以编写一些代码:

    # Base R
    
    # Add "commas" to sep each element
    new_json_str <- paste(my_df$column_1, collapse = ",")
    
    # Add "brackets" to the string
    new_json_str <- paste("[", new_json_str, "]")
    
    # Parse the JSON string with jsonlite
    jsonlite::fromJSON(new_json_str)
    
    
    # With dplyr library
    
    my_df %>% 
        pull(column_1) %>%              # Get column as "vector"
        paste(collapse = ",") %>%       # Add "commas"
        paste("[", . ,"]") %>%          # Add "bracket" (`.` represents the current value, in this case vectors sep by ",")
        jsonlite::fromJSON()            # Parse json to df
    
    # Result
    
    #    name age   car
    # 1  John  30  <NA>
    # 2 Chuck  25 black
    # 3 David  54  blue
    

    【讨论】:

    • 非常感谢! dplyr 方法效果很好,我在这里有很多东西要学,但我很感激你的帮助。快速问 - JSONlite 如何知道在 JSON 字符串中适当地组织组件?例如,JSON 字符串中的顺序并不一致,但 JSONlite 似乎将所有内容都放入了正确的列中。那是在图书馆里烤的吗?
    • 不客气。我不知道jsonlite 的内部功能,但是我有一个想法。 jsonkey: value 数据对一起使用。因此,从这个意义上讲,jsonlite“将”key 作为列名,将value 作为行的“当前”值。如果value 不存在,它将用NA 填充。
    【解决方案2】:

    或者,可以使用RcppSimdJson 包。根据数据文件的格式我们可以

    • 要么使用fparse()逐行转换数据
    • 或使用fload()一次性读取和转换文件

    逐行转换数据

    如果数据文件json_data_1.csv有格式

    {"name":"John", "age":30, "car":null}
    {"name":"Chuck", "car":"black", "age":25}
    {"car":"blue", "age":54, "name":"David"}
    

    (请注意,blueblack 已用双引号括起来以遵守 JSON 语法规则)

    JSON数据需要逐行转换,例如

    library(magrittr)   # piping used to improve readability
    readLines("json_data_1.csv") %>% 
      lapply(RcppSimdJson::fparse) %>% 
      data.table::rbindlist(fill = TRUE)
    
        name age   car
    1:  John  30  <NA>
    2: Chuck  25 black
    3: David  54  blue
    

    一次读取和转换文件

    如果数据文件json_data_2.csv有格式

    [
    {"name":"John", "age":30, "car":null},
    {"name":"Chuck", "car":"black", "age":25},
    {"car":"blue", "age":54, "name":"David"}
    ]
    

    (注意方括号和逗号表示 JSON 语法中的数组)

    文件可以通过一行代码读取和转换:

    RcppSimdJson::fload("json_data_2.csv")
    
       name age   car
    1  John  30  <NA>
    2 Chuck  25 black
    3 David  54  blue
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-20
      • 2015-02-15
      • 2020-07-31
      • 1970-01-01
      • 2011-03-14
      • 2016-02-21
      • 1970-01-01
      相关资源
      最近更新 更多