Stratégies pour la mise en forme de JSON sortie de R
Je suis à essayer de comprendre la meilleure façon de produire un fichier JSON à partir de R. j'ai le texte suivant dataframe tmp
dans R
.
> tmp
gender age welcoming proud tidy unique
1 1 30 4 4 4 4
2 2 34 4 2 4 4
3 1 34 5 3 4 5
4 2 33 2 3 2 4
5 2 28 4 3 4 4
6 2 26 3 2 4 3
La sortie de dput(tmp)
est comme suit:
tmp <- structure(list(gender = c(1L, 2L, 1L, 2L, 2L, 2L), age = c(30,
34, 34, 33, 28, 26), welcoming = c(4L, 4L, 5L, 2L, 4L, 3L), proud = c(4L,
2L, 3L, 3L, 3L, 2L), tidy = c(4L, 4L, 4L, 2L, 4L, 4L), unique = c(4L,
4L, 5L, 4L, 4L, 3L)), .Names = c("gender", "age", "welcoming",
"proud", "tidy", "unique"), na.action = structure(c(15L, 39L,
60L, 77L, 88L, 128L, 132L, 172L, 272L, 304L, 305L, 317L, 328L,
409L, 447L, 512L, 527L, 605L, 618L, 657L, 665L, 670L, 708L, 709L,
729L, 746L, 795L, 803L, 826L, 855L, 898L, 911L, 957L, 967L, 983L,
984L, 988L, 1006L, 1161L, 1162L, 1224L, 1245L, 1256L, 1257L,
1307L, 1374L, 1379L, 1386L, 1387L, 1394L, 1401L, 1408L, 1434L,
1446L, 1509L, 1556L, 1650L, 1717L, 1760L, 1782L, 1814L, 1847L,
1863L, 1909L, 1930L, 1971L, 2004L, 2022L, 2055L, 2060L, 2065L,
2082L, 2109L, 2121L, 2145L, 2158L, 2159L, 2226L, 2227L, 2281L
), .Names = c("15", "39", "60", "77", "88", "128", "132", "172",
"272", "304", "305", "317", "328", "409", "447", "512", "527",
"605", "618", "657", "665", "670", "708", "709", "729", "746",
"795", "803", "826", "855", "898", "911", "957", "967", "983",
"984", "988", "1006", "1161", "1162", "1224", "1245", "1256",
"1257", "1307", "1374", "1379", "1386", "1387", "1394", "1401",
"1408", "1434", "1446", "1509", "1556", "1650", "1717", "1760",
"1782", "1814", "1847", "1863", "1909", "1930", "1971", "2004",
"2022", "2055", "2060", "2065", "2082", "2109", "2121", "2145",
"2158", "2159", "2226", "2227", "2281"), class = "omit"), row.names = c(NA,
6L), class = "data.frame")
À l'aide de la rjson
paquet, j'ai exécuter la ligne de toJSON(tmp)
qui produit le texte suivant fichier JSON:
{"gender":[1,2,1,2,2,2],
"age":[30,34,34,33,28,26],
"welcoming":[4,4,5,2,4,3],
"proud":[4,2,3,3,3,2],
"tidy":[4,4,4,2,4,4],
"unique":[4,4,5,4,4,3]}
J'ai également expérimenté avec la RJSONIO
paquet; la sortie de toJSON()
était le même. Ce que je voudrais présenter la structure suivante:
{"traits":["gender","age","welcoming","proud", "tidy", "unique"],
"values":[
{"gender":1,"age":30,"welcoming":4,"proud":4,"tidy":4, "unique":4},
{"gender":2,"age":34,"welcoming":4,"proud":2,"tidy":4, "unique":4},
....
]
Je ne suis pas sûr de la meilleure façon de le faire. Je me rends compte que j'ai peut l'analyser ligne par ligne à l'aide de python
mais je pense qu'il y a sans doute une meilleure façon de le faire. Je me rends compte que ma structure de données dans R
ne reflète pas la méta-information désirée dans mon JSON
fichier (en particulier le traits
ligne), mais je m'intéresse principalement à la production de données formatés comme la ligne
{"gender":1,"age":30,"welcoming":4,"proud":4,"tidy":4, "unique":4}
que je peux ajouter manuellement la première ligne.
EDIT: j'ai trouvé utile blog post où l'auteur traite d'un problème similaire et a fourni une solution. Cette fonction donne la forme d'un fichier JSON à partir d'un bloc de données.
toJSONarray <- function(dtf){
clnms <- colnames(dtf)
name.value <- function(i){
quote <- '';
# if(class(dtf[, i])!='numeric'){
if(class(dtf[, i])!='numeric' && class(dtf[, i])!= 'integer'){ # I modified this line so integers are also not enclosed in quotes
quote <- '"';
}
paste('"', i, '" : ', quote, dtf[,i], quote, sep='')
}
objs <- apply(sapply(clnms, name.value), 1, function(x){paste(x, collapse=', ')})
objs <- paste('{', objs, '}')
# res <- paste('[', paste(objs, collapse=', '), ']')
res <- paste('[', paste(objs, collapse=',\n'), ']') # added newline for formatting output
return(res)
}
- Les années ont passé depuis que cette question a été posée. Je suggère à la recherche à la bibliothèque(jsonlite) - quelqu'un d'autre a fourni la réponse ci-dessous. Il ne nécessite pas l'appliquer() transforme et produit directement de l'attendu la sortie JSON.
- marqué jsonlite comme réponse
Vous devez vous connecter pour publier un commentaire.
À l'aide du package
jsonlite
:Bâtiment sur Andrie de l'idée avec
apply
, vous pouvez obtenir exactement ce que vous voulez en modifiant latmp
variable avant d'appelertoJSON
.rjson
etRJSONIO
), c'est qu'ils convertir tous les numéros de chaînes. Par exemple2
devient"2"
. L'extrait de code, j'ai collé à ma question permet d'éviter ce problème, tel qu'il vérifienumeric
etinteger
. Peut-être que je devrais l'ajouter comme une réponse.tmp
a entier entiers, pas converti en chaîne de nombres entiers. Êtes-vous sûr de ne pas faire quelque chose de stupide?toJSON
fonction.De renforcer Andrie et de Richie idées, l'utilisation
alply
au lieu deapply
pour éviter la conversion d'un nombre de caractères:plyr de
alply
est similaire àapply
mais renvoie une liste automatiquement; que, sans la plus compliquée de la fonction à l'intérieur de Richie Coton réponse,apply
serait de retour d'un vecteur ou d'une matrice. Et ces étapes supplémentaires, y comprist
, signifie que si votre jeu de données non-colonnes numériques, les nombres sont convertis en chaînes.Afin que l'utilisation de
alply
évite ce souci.Par exemple, prenez votre
tmp
dataset et ajouterEnsuite comparer ce code (avec
alply
) vs l'autre exemple (avecapply
).Il me semble que vous pouvez le faire en envoyant chaque ligne de votre
data.frame
en JSON avec leapply
déclaration.Pour une seule ligne:
L'ensemble de la
data.frame
:,
à la fin de chaque ligne en utilisant quelque chose comme ceci:x <- apply(tmp, 1, function(tmp){paste(toJSON, ',')})
. Est-il un moyen d'ajouter quelque chose à ce qui est retournée à partir detoJSON
?x <- apply(tmp, 1, function(tmp){paste(toJSON(tmp), ',')})
. Toujours obtenir le coup de l'apply
!toJSON
vous donne ce que vous voulez. Voir ma réponse.,
entre{...}{...}
. La sortie qui a été produit n'a pas été JSON valide. Je suis d'accord en général cependant, il n'est probablement pas un bon moyen de le faire.Une autre option est d'utiliser le
split
diviser votredata.frame
avec N lignes en N de données.cadres avec 1 ligne.