【问题标题】:R data.frame to JSON with child nodes / hierarchicalR data.frame 到带有子节点/分层的 JSON
【发布时间】:2015-04-28 21:42:24
【问题描述】:

我正在尝试将 R 中的 data.frame 写入 JSON 文件,但采用分层结构,其中包含子节点。我找到了示例和 JSONIO,但无法将其应用于我的案例。

这是R中的data.frame

> DF
   Date_by_Month    CCG Year Month refYear      name OC_5a OC_5b OC_5c 
1     2010-01-01 MyTown 2010    01    2009 2009/2010     0    15    27 
2     2010-02-01 MyTown 2010    02    2009 2009/2010     1    14    22 
3     2010-03-01 MyTown 2010    03    2009 2009/2010     1     6    10 
4     2010-04-01 MyTown 2010    04    2010 2010/2011     0    10    10 
5     2010-05-01 MyTown 2010    05    2010 2010/2011     1    16     7 
6     2010-06-01 MyTown 2010    06    2010 2010/2011     0    13    25 

除了按月编写数据外,我还想创建一个聚合子节点,即“每年”的子节点,它包含今年所有月份的总和(例如)。这就是我希望 JSON 文件的样子:

[
    {
     "ccg":"MyTown",
     "data":[
            {"period":"yearly",
             "scores":[
                {"name":"2009/2010","refYear":"2009","OC_5a":2, "OC_5b": 35, "OC_5c": 59},
                {"name":"2010/2011","refYear":"2010","OC_5a":1, "OC_5b": 39, "OC_5c": 42},
             ]
             },
            {"period":"monthly",
             "scores":[
                {"name":"2009/2010","refYear":"2009","month":"01","year":"2010","OC_5a":0, "OC_5b": 15, "OC_5c": 27},
                {"name":"2009/2010","refYear":"2009","month":"02","year":"2010","OC_5a":1, "OC_5b": 14, "OC_5c": 22},
                {"name":"2009/2010","refYear":"2009","month":"03","year":"2010","OC_5a":1, "OC_5b": 6, "OC_5c": 10},
                {"name":"2009/2010","refYear":"2009","month":"04","year":"2010","OC_5a":0, "OC_5b": 10, "OC_5c": 10},
                {"name":"2009/2010","refYear":"2009","month":"05","year":"2010","OC_5a":1, "OC_5b": 16, "OC_5c": 7},
                {"name":"2009/2010","refYear":"2009","month":"01","year":"2010","OC_5a":0, "OC_5b": 13, "OC_5c": 25}
                ]
             }
            ]
    },
]

非常感谢您的帮助!

【问题讨论】:

  • jsonlite 包有很多特性,但你所描述的并没有真正映射到数据框,所以我怀疑 any 罐装例程有这个功能。您最好的选择可能是将数据框转换为更通用的列表(仅供参考的数据框在内部存储为列列表),其结构与 JSON 的结构完全匹配,然后只需使用转换器进行翻译

标签: json r hierarchical rjsonio


【解决方案1】:

扩展我的评论:

jsonlite 包有很多功能,但是您所描述的内容并没有真正映射到数据框,所以我怀疑任何罐装例程都具有此功能。您最好的选择可能是将数据框转换为更通用的列表(仅供参考的数据框在内部存储为列列表),其结构与 JSON 的结构完全匹配,然后只需使用转换器进行翻译

这通常很复杂,但在您的情况下应该相当简单。该列表的结构将与 JSON 数据完全相同:

list(
  list(
    ccg = "Town1",
    data = list(
      list(
        period = "yearly",
        scores = yearly_data_frame_town1
      ),
      list(
        period = "monthly",
        scores = monthly_data_frame_town1
      )
    )
  ),
  list(
    ccg = "Town2",
    data = list(
      list(
        period = "yearly",
        scores = yearly_data_frame_town2
      ),
      list(
        period = "monthly",
        scores = monthly_data_frame_town2
      )
    )
  )
)

构造这个列表应该是一个简单的例子,循环unique(DF$CCG)并在每一步使用aggregate来构造年度数据。

如果您需要性能,请查看data.tabledplyr 包来一次性完成循环和聚合。前者灵活且高效,但有点深奥。后者具有相对简单的语法并且具有类似的性能,但它是专门围绕为数据帧构建管道而设计的,因此可能需要进行一些黑客攻击才能使其产生正确的输出格式。

【讨论】:

  • @Sylvia 你在用jsonlite吗?我用“iris”数据集测试了jsonlite::toJSON,它为数据框中的每一行创建了一个映射。很有可能,您的数据框在某个时候被转置(我认为 aggregate 做了一些奇怪的转置)。
  • 是的,我这次尝试使用 jsonlite(而不是 JSONIO),并且 toJSON 函数允许我控制我是指行还是列 - 所以我认为我在这里越来越接近解决方案!谢谢!
【解决方案2】:

看起来 ssdecontrol 已经涵盖了您...但这是我的解决方案。需要遍历独特的 CCG 和 Years 来创建整个数据集...

df <- read.table(textConnection("Date_by_Month    CCG Year Month refYear      name OC_5a OC_5b OC_5c 
2010-01-01 MyTown 2010    01    2009 2009/2010     0    15    27 
2010-02-01 MyTown 2010    02    2009 2009/2010     1    14    22 
2010-03-01 MyTown 2010    03    2009 2009/2010     1     6    10 
2010-04-01 MyTown 2010    04    2010 2010/2011     0    10    10 
2010-05-01 MyTown 2010    05    2010 2010/2011     1    16     7 
2010-06-01 MyTown 2010    06    2010 2010/2011     0    13    25"), stringsAsFactors=F, header=T)


library(RJSONIO)
to_list <- function(ccg, year){
  df_monthly <- subset(df, CCG==ccg & Year==year)
  df_yearly <- aggregate(df[,c("OC_5a", "OC_5b", "OC_5c")] ,df[,c("name", "refYear")], sum)
  l <- list("ccg"=ccg, 
            data=list(list("period" = "yearly",
                      "scores" = as.list(df_yearly)
                      ),
                      list("period" = "monthly",
                           "scores" = as.list(df[,c("name", "refYear", "OC_5a", "OC_5b", "OC_5c")])
                      )
            )
       )
  return(l)
}
toJSON(to_list("MyTown", "2010"), pretty=T)

返回这个:

{
    "ccg" : "MyTown",
    "data" : [
        {
            "period" : "yearly",
            "scores" : {
                "name" : [
                    "2009/2010",
                    "2010/2011"
                ],
                "refYear" : [
                    2009,
                    2010
                ],
                "OC_5a" : [
                    2,
                    1
                ],
                "OC_5b" : [
                    35,
                    39
                ],
                "OC_5c" : [
                    59,
                    42
                ]
            }
        },
        {
            "period" : "monthly",
            "scores" : {
                "name" : [
                    "2009/2010",
                    "2009/2010",
                    "2009/2010",
                    "2010/2011",
                    "2010/2011",
                    "2010/2011"
                ],
                "refYear" : [
                    2009,
                    2009,
                    2009,
                    2010,
                    2010,
                    2010
                ],
                "OC_5a" : [
                    0,
                    1,
                    1,
                    0,
                    1,
                    0
                ],
                "OC_5b" : [
                    15,
                    14,
                    6,
                    10,
                    16,
                    13
                ],
                "OC_5c" : [
                    27,
                    22,
                    10,
                    10,
                    7,
                    25
                ]
            }
        }
    ]
}

【讨论】:

  • 这遇到了@Sylvia 描述的同一个转置问题。尝试jsonlite 包(这是我使用的,显然它更好)并检查以确保aggregate 没有默默地转置任何东西。
猜你喜欢
  • 1970-01-01
  • 2021-12-01
  • 2017-04-21
  • 1970-01-01
  • 2019-07-27
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多