2

如何将具有分层信息的 data.frame 转换为 JSON(或嵌套列表)?

假设我们有以下data.frame:

df <- data.frame(
  id = c('1', '1.1', '1.1.1', '1.2'), 
  value = c(10, 5, 5, 5)) 

#  id   value
#     1    10
#   1.1     5
# 1.1.1     5
#   1.2     5

然后我想以以下 JSON 结尾:

{
 "id": "1",
 "value": 10,
 "children": [
  {
   "id": "1.1",
   "value": 5,
   "children": [
    {
     "id": "1.1.1", 
     "value": 5 
    }
   ]
  },
  {
   "id": "1.2",
   "value": 5
  }
 ]
}

whereid定义了层次结构,并且.是一个分隔符。

我的目的是能够轻松地将数据从 R 转换为分层 D3 可视化(例如分区布局可缩放树形图)。如果可以添加更多“价值”列,那就太好了;例如value, size,weight等。

谢谢!

编辑:我恢复到原来的问题,所以更容易理解所有的答案(对不起所有的编辑)。

4

2 回答 2

3

我倾向于RJSONIO安装它:

R> df <- data.frame(id = c('1', '1.1', '1.1.1', '1.2'), value = c(10, 5, 5, 5)) 
R> RJSONIO::toJSON(df)
[1] "{\n \"id\": [ \"1\", \"1.1\", \"1.1.1\", \"1.2\" ],\n\"value\": [     10,      5,      5,      5 ] \n}"
R> cat(RJSONIO::toJSON(df), "\n")
{
 "id": [ "1", "1.1", "1.1.1", "1.2" ],
"value": [     10,      5,      5,      5 ] 
} 
R> 

不是您想要的输出,但 data.frame 中存在所需的嵌套/层次结构。我认为,如果您将 data.frame 嵌套在列表中,您将到达那里。

编辑:对于您修改后的问题,这里是读取您指定的 JSON 的 R 输出:

R> RJSONIO::fromJSON("/tmp/foo.json")
$id
[1] "1"

$value
[1] 10

$children
$children[[1]]
$children[[1]]$id
[1] "1.1"

$children[[1]]$value
[1] 5

$children[[1]]$children
$children[[1]]$children[[1]]
$children[[1]]$children[[1]]$id
[1] "1.1.1"

$children[[1]]$children[[1]]$value
[1] 5




$children[[2]]
$children[[2]]$id
[1] "1.2"

$children[[2]]$value
[1] 5



R> 
于 2013-01-25T20:13:12.590 回答
1

一个可能的解决方案。

首先,我定义了以下函数:

# Function to get the number hierarchical dimensions (occurences of "." + 1)
ch_dim <- function(x, delimiter = ".") {
    x <- as.character(x)
    chr.count <- function(x) length(which(unlist(strsplit(x, NULL)) == delimiter))
    if (length(x) > 1) {
        sapply(x, chr.count) + 1
    } else {
        chr.count(x) + 1
    }
}

# Function to convert a hierarchical data.frame to a nested list
lst_fun <- function(ch, id_col = "id", num = min(d), stp = max(d)) {

    # Convert data.frame to character
    ch <- data.frame(lapply(ch, as.character), stringsAsFactors=FALSE)

    # Get number of hierarchical dimensions
    d <- ch_dim(ch[[id_col]])

    # Convert to list
    lapply(ch[d == num,][[id_col]], function(x) {
        tt <- ch[grepl(sprintf("^%s.", x), ch[[id_col]]),]
        current <- ch[ch[[id_col]] == x,]
        if (stp != num && nrow(tt) > 0) { 
            c(current, list(children = lst_fun(tt, id_col, num + 1, stp)))
        } else { current }
    })
}

然后将 data.frame 转换为列表:

lst <- lst_fun(df, "id")

最后是 JSON:

s <- RJSONIO::toJSON(lst)
于 2013-01-29T07:39:18.727 回答