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.
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:
- unnamed list (or vector)
- named list (or vector)
- 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 }'
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 ]
}
]
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
}
]
}
]