Converting a matrix/dataframe in R to JSON object with some constraints

梦想的初衷 提交于 2019-12-08 08:52:29

问题


REDITED:

I have to convert a matrix in R to a JSON object with some structure in it. I am using the rjson package. Through an example, let me illustrate what I want. My specific case is the output of a recommender system code in R where the X2 X3 are the 2 closest items to a particular item X1. Also, X4,X5 are the scores of similarity associated with (X1,X2) and (X1,X3) for that row. I want all the recommended items for every item as JSON objects and every item along with its recommended JSON object- items as a bigger JSON objects.The scores should also be incorporated into the JSON structure.

Let me explain through a example.

Suppose I have a matrix

X1 X2 X3 X4 X5 
1 22 23  0.8 0.5
34 4 87  0.4 0.4
23 7 92  0.6 0.5

I want a JSON structure for every item (every X1 for every row) along with the recommended items and the similarity scores for each combination as a separate JSON entity and this being done in sequence. I don't want an entire JSON object containing these individual ones. Assume there is one more entity called "coid" that will be given as input to the code. I assume it is XYZ and it is same for all the rows.

{ "_id" : { "coid" : "XYZ", "iid" : "1"}, "items" : [ { "item" : "22", "score" : 0.8},{ "item": "23", "score" : 0.5}] }
{ "_id" : { "coid" : "XYZ", "iid" : "34"},"items" : [ { "item" : "4", "score" : 0.4},{ "item": "87", "score" : 0.4}] }
{ "_id" : { "coid" : "XYZ", "iid" : "23"},"items" : [ { "item" : "7", "score" : 0.6},{ "item": "92", "score" : 0.5}] }

As in the above, each entity is a valid JSON structure/object but they are not put together into a separate JSON object as a whole.

I appreciate all the help done for the previous question but somehow I feel this new alteration I have here is not related to them because in the end, if you do a toJSON(some entity), then it converts the entire thing to one JSON object. I don't want that. I want individual ones like these to be written to a file.

I am very sorry for my ignorance and inconvenience. Please help. Thanks.


回答1:


First of all, your json is not valid. You can check the validity for example here.

That being said, to get something similar to your desired json output, you can do as f

library(RJSONIO)

# recreating your matrix
m <- matrix(c(1,22,23,34,4,87,23,7,92),nrow=3,byrow=T)
colnames(m)<-c('X1','X2','X3')

# convert numeric matrix to character (if necessary)
m <- matrix(as.character(m),nrow=nrow(m))

# transform your matrix before turning into json    
p <- apply(m,MARGIN=1,FUN=function(r)list(Item=unname(r[1]),Recos=unname(r[-1])))

# jsonize
toJSON(p)

Result:

[
    {
        "Item" : "1",
        "Recos" : ["22", "23"]
    },
    {
        "Item" : "34",
        "Recos" : ["4", "87"]
    },
    {
        "Item" : "23",
        "Recos" : ["7", "92"]
    }
]

EDIT (as per your edit) :

library(RJSONIO)

# recreating your matrix
m <- matrix(c(1,22,23,34,4,87,23,7,92),nrow=3,byrow=T)
colnames(m)<-c('X1','X2','X3')

# transform your matrix before turning into json    
p <- apply(m,MARGIN=1,
           FUN=function(r){
             list(itemID=unname(r[1]),
                  recommendedItems=lapply(unname(r[-1]),
                                          FUN=function(i)list(itemID=i)))
           })

# jsonize
toJSON(p)

Result:

[{
        "itemID" : 1,
        "recommendedItems" : [{
                "itemID" : 22
            }, {
                "itemID" : 23
            }
        ]
    }, {
        "itemID" : 34,
        "recommendedItems" : [{
                "itemID" : 4
            }, {
                "itemID" : 87
            }
        ]
    }, {
        "itemID" : 23,
        "recommendedItems" : [{
                "itemID" : 7
            }, {
                "itemID" : 92
            }
        ]
    }
]

EDIT 2 :

Instead of writing the code for you, I'd rather try to explain how an R structure is turned into a json by RJSONIO package.

As far as json conversion is concerned, I consider 3 "kind" of objects:

  1. unnamed list (or vector)
  2. named list (or vector)
  3. vector of one element

1) An unnamed list (or vector) of elements (e.g. v <- list('a','b','c')), is translated to json as:

[ element_1, element_2, element_3, ... ]

with element_n being the n-th element of the list. Of course each element of the list can be, in turn, another complex object that is turned into json following the 3 rules I am describing here.

2) A named list (or vector) (e.g. n <- list(A="foo",B="bar")), is translated to json as:

{ "name_1": value_1, "name_2": value_2, ...  }

with name_n being the name of the n-th element of the named list, and value_1 the value of the n-th element of the named list. Of course each value of the named list can be, in turn, another complex object that is turned into json following the 3 rules I am describing here.

3) As you could correctly point out, every object in R is a vector. Even a <- 1 is a numeric vector of one element. So, following the previous 2 rules, you would expect for example list(x=1) to be translated as { "x" : [ 1 ] }. But thanks to parameter asIs (FALSE by default) of toJSON function, vectors (not lists) of single elements are considered scalars.

That being said, here follows some examples:

toJSON(list(list(A=2),1:3))
> '[ { "A": 2 }, [ 1, 2, 3 ] ]'

toJSON(list(A=list(1),B=list(C="X"),D=1))
> '{ "A": [ 1 ], "B": { "C": "X" }, "D": 1 }'



回答2:


The desired json object is not a valid. You should transform your data.frame to a list before transforming it to a json object. For example you can do this:

cat(toJSON(apply(dat,1,function(x)list(item =unname(x[1]),
                                       Recos=unname(x[-1])))))

[
 {
 "item": 1,
"Recos": [ 22, 23 ] 
},
{
 "item": 34,
"Recos": [ 4, 87 ] 
},
{
 "item": 23,
"Recos": [ 7, 92 ] 
} 
]



回答3:


You need to create the appropriately nested list

m <- matrix(c(1,22,23,34,4,87,23,7,92),nrow=3,byrow=T)
colnames(m)<-c('X1','X2','X3')

m1 <- apply(m,1, function(x) {
     list(itemID = unname(x[1]), 
          recommendedItems = lapply(unname(x[2:3]), function(y) {
             list(itemID = y)}
          ))
       })


 cat(toJSON(m1))
[
  {
    "itemID":      1,
    "recommendedItems": [
      {
        "itemID":     22 
      },
      {
        "itemID":     23 
      } 
    ] 
  },
{
    "itemID":     34,
    "recommendedItems": [
      {
        "itemID":      4 
      },
      {
        "itemID":     87 
      } 
    ] 
  },
{
    "itemID":     23,
    "recommendedItems": [
      {
        "itemID":      7 
      },
      {
        "itemID":     92 
      } 
    ] 
  } 
]


来源:https://stackoverflow.com/questions/24840182/converting-a-matrix-dataframe-in-r-to-json-object-with-some-constraints

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!