【问题标题】:Generate Nested JSON Using R使用 R 生成嵌套 JSON
【发布时间】:2020-02-20 01:57:03
【问题描述】:

我正在尝试使用 R 生成一个嵌套的 JSON 文件,但在设置它时遇到了困难。诚然,我对 JSON 很陌生,所以在概念上我落后了。我将不胜感激 - 包括关于可以使这项任务更容易的地方(R 除外)的建议。

我正在使用 3 个数据集 - 全部通过键连接。本质上,我的目标是创建一个 JSON 文件,其中包含患者对象、嵌套的遭遇以及在这些遭遇中嵌套的声明行。

这是 R 中的设置:

patients <- data.frame (
                      PatientID = c('PID01','PID02'),
                      PatientName = c('John Doe','Jane Doe'),
                      PatientGroup = c('Group A','Group B')
                    )

encounters <- data.frame (
                          EncounterID = c('Enc01','Enc02','Enc03','Enc04','Enc05'),
                          PatientID = c('PID01','PID01','PID02','PID02','PID02'),
                          EncounterType = c('Outpatient','Outpatient','Inpatient','Outpatient','SNF')
                         )

encounterLines <- data.frame (
                              EncounterID = c(rep('Enc01',5),rep('Enc04',2)),
                              RevCodes = c('001','100','200','300','400','001','100'),
                              ClaimLine = c(seq(1:5),seq(1:2))
                              )

 ----------------------------------------
 PatientID   PatientName   PatientGroup 
----------- ------------- --------------
   PID01      John Doe       Group A    

   PID02      Jane Doe       Group B    
----------------------------------------

-----------------------------------------
 EncounterID   PatientID   EncounterType 
------------- ----------- ---------------
    Enc01        PID01      Outpatient   

    Enc02        PID01      Outpatient   

    Enc03        PID02       Inpatient   

    Enc04        PID02      Outpatient   

    Enc05        PID02          SNF      
-----------------------------------------

------------------------------------
 EncounterID   RevCodes   ClaimLine 
------------- ---------- -----------
    Enc01        001          1     

    Enc01        100          2     

    Enc01        200          3     

    Enc01        300          4     

    Enc01        400          5     

    Enc04        001          1     

    Enc04        100          2     
------------------------------------

我正在寻找的 JSON 输出如下。我尝试过使用jsonlite,但我似乎无法获得任何真正的吸引力:

[
    {
        "PatientID": "PID01",
        "PatientName": "John Doe",
        "PatientGroup": "Group A",
        "Encounters": [
            {
                "EncounterID": "Enc01",
                "EncounterType": "Outpatient",
                "ClaimLines": [
                    {
                        "ClaimLine": 1,
                        "RevenueCode": "001"
                    },
                    {
                        "ClaimLine": 2,
                        "RevenueCode": "100"
                    },
                    {
                        "ClaimLine": 3,
                        "RevenueCode": "200"
                    },
                    {
                        "ClaimLine": 4,
                        "RevenueCode": "300"
                    },
                    {
                        "ClaimLine": 5,
                        "RevenueCode": "400"
                    }
                ]
            },
            {
                "EncounterID": "Enc02",
                "EncounterType": "Outpatient"
            }
        ]
    },
    {
        "PatientID": "PID02",
        "PatientName": "Jane Doe",
        "PatientGroup": "Group B",
        "Encounters": [
            {
                "EncounterID": "Enc03",
                "EncounterType": "Inpatient"
            },
            {
                "EncounterID": "Enc04",
                "EncounterType": "Outpatient",
                "ClaimLines": [
                    {
                        "ClaimLine": 1,
                        "RevenueCode": "001"
                    },
                    {
                        "ClaimLine": 2,
                        "RevenueCode": "100"
                    }
                ]
            },
            {
                "EncounterID": "Enc05",
                "EncounterType": "SNF"
            }
        ]
    }
]

任何/所有帮助将不胜感激。正如我之前提到的,我并不反对使用 R 之外的工具。

谢谢!

【问题讨论】:

    标签: r arrays json object jsonlite


    【解决方案1】:

    这似乎非常接近

    library(tidyverse)
    library(jsonlite)
    
    json <- reduce(list(
        patients %>% mutate_if(is.factor, as.character),
        encounters %>% mutate_if(is.factor, as.character),
        encounterLines %>%
            mutate_if(is.factor, as.character) %>%
            group_by(EncounterID) %>%
            nest() %>%
            rename(ClaimLines = data) %>%
            mutate(ClaimLines = map(ClaimLines, transpose))),
        left_join) %>%
        nest(Encounters = c(EncounterID, EncounterType, ClaimLines)) %>%
        transpose() %>%
        toJSON(pretty = TRUE)
    #[
    #  {
    #    "PatientID": ["PID01"],
    #    "PatientName": ["John Doe"],
    #    "PatientGroup": ["Group A"],
    #    "Encounters": [
    #      {
    #        "EncounterID": "Enc01",
    #        "EncounterType": "Outpatient",
    #        "ClaimLines": [
    #          {
    #            "RevCodes": ["001"],
    #            "ClaimLine": [1]
    #          },
    #          {
    #            "RevCodes": ["100"],
    #            "ClaimLine": [2]
    #          },
    #          {
    #            "RevCodes": ["200"],
    #            "ClaimLine": [3]
    #          },
    #          {
    #            "RevCodes": ["300"],
    #            "ClaimLine": [4]
    #          },
    #          {
    #            "RevCodes": ["400"],
    #            "ClaimLine": [5]
    #          }
    #        ]
    #      },
    #      {
    #        "EncounterID": "Enc02",
    #        "EncounterType": "Outpatient",
    #        "ClaimLines": {}
    #      }
    #    ]
    #  },
    #  {
    #    "PatientID": ["PID02"],
    #    "PatientName": ["Jane Doe"],
    #    "PatientGroup": ["Group B"],
    #    "Encounters": [
    #      {
    #        "EncounterID": "Enc03",
    #        "EncounterType": "Inpatient",
    #        "ClaimLines": {}
    #      },
    #      {
    #        "EncounterID": "Enc04",
    #        "EncounterType": "Outpatient",
    #        "ClaimLines": [
    #          {
    #            "RevCodes": ["001"],
    #            "ClaimLine": [1]
    #          },
    #          {
    #            "RevCodes": ["100"],
    #            "ClaimLine": [2]
    #          }
    #        ]
    #      },
    #      {
    #        "EncounterID": "Enc05",
    #        "EncounterType": "SNF",
    #        "ClaimLines": {}
    #      }
    #    ]
    #  }
    #]
    #
    

    关键是首先创建一个合适的嵌套list(使用多个purrr::transposes),然后使用jsonlite::toJSON将其正确转换为嵌套JSON。

    【讨论】:

    • 谢谢!不过,我收到了这个错误:Error in mutate_impl(.data, dots) : Cannot convert object to a function: [type=NULL; target=CLOSXP, SPECIALSXP, or BUILTINSXP].
    • 嗯,根据您提供的示例数据,我无法重现。您是否使用最新版本的 tidyverse 软件包? tidyrpurrr 的最新版本有一些(重大的)变化。我已经在 tidyr_1.0.0purrr_0.3.3 上检查过了。
    • 看起来我使用的是旧版本。软件包更新纠正了我的问题。谢谢!
    【解决方案2】:

    几个data.table 加入,你也可以到达那里

    library(data.table)
    setDT( patients )
    setDT( encounters )
    setDT( encounterLines )
    
    ## do a 'left-join' by putting 
    ## encounterLines onto encounters
    dt_encounters <- encounterLines[
      encounters
      , on = "EncounterID"
      , nomatch = NA       ## indicates left-join
    ]
    
    ## make a list-column (required for JSON)
    dt_encounters <- dt_encounters[
      , .(ClaimLines = list(.SD))
      , by = .(EncounterID, EncounterType, PatientID)
    ]
    
    ## do a 'left-join' by putting
    ## encounters onto patients
    dt_patients <- dt_encounters[
      patients
      , on = "PatientID"
      , nomatch = NA
    ]
    
    ## make a list-column (required for JSON)
    dt_patients <- dt_patients[
      , .(Encounters = list(.SD))
      , by = .(PatientID, PatientName, PatientGroup)
    ] 
    
    toJSON( dt_patients, pretty = TRUE )
    
    [
      {
        "PatientID": "PID01",
        "PatientName": "John Doe",
        "PatientGroup": "Group A",
        "Encounters": [
          {
            "EncounterID": "Enc01",
            "EncounterType": "Outpatient",
            "ClaimLines": [
              {
                "RevCodes": "001",
                "ClaimLine": 1
              },
              {
                "RevCodes": "100",
                "ClaimLine": 2
              },
              {
                "RevCodes": "200",
                "ClaimLine": 3
              },
              {
                "RevCodes": "300",
                "ClaimLine": 4
              },
              {
                "RevCodes": "400",
                "ClaimLine": 5
              }
            ]
          },
          {
            "EncounterID": "Enc02",
            "EncounterType": "Outpatient",
            "ClaimLines": [
              {}
            ]
          }
        ]
      },
      {
        "PatientID": "PID02",
        "PatientName": "Jane Doe",
        "PatientGroup": "Group B",
        "Encounters": [
          {
            "EncounterID": "Enc03",
            "EncounterType": "Inpatient",
            "ClaimLines": [
              {}
            ]
          },
          {
            "EncounterID": "Enc04",
            "EncounterType": "Outpatient",
            "ClaimLines": [
              {
                "RevCodes": "001",
                "ClaimLine": 1
              },
              {
                "RevCodes": "100",
                "ClaimLine": 2
              }
            ]
          },
          {
            "EncounterID": "Enc05",
            "EncounterType": "SNF",
            "ClaimLines": [
              {}
            ]
          }
        ]
      }
    ]
    
    

    【讨论】:

    • 很好的解决方案!我对data.table 不太熟悉。谢谢分享。
    • @kostr 我添加了一些 cmets 以尝试使每个步骤更清晰。与往常一样,有许多工具可以完成相同的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 2016-06-27
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多