R数据帧到JSON层次结构



我有以下数据帧:

fakedat<-data.frame(name=c("Holdingcompany","Holdingcompany","company1","company1","company2","company2"),children=c("company1","company2","company4","company3","company5","company6"),info=c("text1","text2","text3","text5","othertext","other_text"),percentage=c("100%","100%","60%","75%","80%","70%"))

我希望输出如下:

{"name": "Holdingcompany",
"children": [
{
"name": "company1",
"tooltip": "text1",
"percentage": "100%",
"children": [
{
"name": "company4",
"tooltip": "text3",
"percentage": "60%"
},
{
"name": "company3",
"tooltip": "text5",
"percentage": "75%"
}
]
},
{
"name": "company2",
"tooltip": "text2",
"percentage": "100%",
"children": [
{
"name": "company5",
"tooltip": "othertext",
"percentage": "80%"
},
{
"name": "company6",
"tooltip": "other_text",
"percentage": "70%"
}
]
}
]
}

我尝试了几种不同的解析方法,包括:如何从R 与子级写入json

但不幸的是,我没能像我希望的那样,把上面的代码正确地应用到列表中的孩子身上。

在尝试应用下面提到的可能重复的解决方案时,我遇到了一个递归错误:";C堆栈使用率太接近而无法限制";因为函数似乎在调用自己。

##Adding in IDs
fakedat<-data.frame(id=c(1,2,3,4,5,6),name=c("Holdingcompany","Holdingcompany","company1","company1","company2","company2"),
children=c("company1","company2","company4","company3","company5","company6"),
info=c("text1","text2","text3","text5","othertext","other text"),
percentage=c("100%","50%","60%","75%","80%","70%"))
get_node <- function(df, id) {
node <- as.list(df[df$id == id, c("name", "info", 
"percentage","id")])
names(node) = c("name", "info", "percentage","id")
id1<-df[df$id==id,]$children
if (!is.na(id1)){
child1 <- get_node(df, id)
if(child1$name == node$name){
node$children <- list(child1)}
node
}
}

jsonlite::toJSON(get_node(fakedat,6), pretty = TRUE, auto_unbox = 
TRUE)`
Error: C stack usage  7972496 is too close to the limit

考虑用merge准备父子关系,然后遍历根/父/子的每个级别,用嵌套的lapply:构建嵌套列表

数据准备

### MERGE DATA
merge_df <- merge(fakedat, fakedat, by.x="children", by.y="name")
merge_df
#   children           name info.x percentage.x children.y     info.y percentage.y
# 1 company1 Holdingcompany  text1         100%   company4      text3          60%
# 2 company1 Holdingcompany  text1         100%   company3      text5          75%
# 3 company2 Holdingcompany  text2         100%   company5  othertext          80%
# 4 company2 Holdingcompany  text2         100%   company6 other_text          70%
nested_df <- unique(merge_df[c("children", "name", "info.x", "percentage.x")])
nested_df
#   children           name info.x percentage.x
# 1 company1 Holdingcompany  text1         100%
# 3 company2 Holdingcompany  text2         100%
top_level_val <- unique(merge_df$name)
top_level_val
# [1] "Holdingcompany"

JSON构建

output <- lapply(top_level_val, function(root) {  
root_lst <- list(
name = root
)

root_lst$children <- lapply(1:nrow(nested_df), function(i) {
chld_mrg <- merge(nested_df[nested_df$children == nested_df$children[i],], merge_df)

parent_lst <- list(
name = nested_df$children[i][1],
tooltip = nested_df$info.x[i][1],
percentage = nested_df$percentage.x[i][1]
)

parent_lst$children <- lapply(1:nrow(chld_mrg), function(j) 
list(
name = merge_df$children.y[j][1],
tooltip = merge_df$info.y[j][1],
percentage = merge_df$percentage.y[j][1]
)
)

return(parent_lst)
})

return(root_lst)
})
# CONVERT TO JSON STRING
jdata <- toJSON(output[[1]], pretty=TRUE, auto_unbox=TRUE)
# WRITE TO DISK
fileConn <- file("NestParentChildJSON.json")
writeLines(jdata, fileConn)
close(fileConn)

输出

{
"name": "Holdingcompany",
"children": [
{
"name": "company1",
"tooltip": "text1",
"percentage": "100%",
"children": [
{
"name": "company4",
"tooltip": "text3",
"percentage": "60%"
},
{
"name": "company3",
"tooltip": "text5",
"percentage": "75%"
}
]
},
{
"name": "company2",
"tooltip": "text2",
"percentage": "100%",
"children": [
{
"name": "company4",
"tooltip": "text3",
"percentage": "60%"
},
{
"name": "company3",
"tooltip": "text5",
"percentage": "75%"
}
]
}
]
}

最新更新