J'ai une table de données où l'une des colonnes contient JSON. J'essaie d'extraire le contenu pour que chaque variable soit une colonne.R convertir json pour lister data.table
library(jsonlite)
library(data.table)
df<-data.table(a=c('{"tag_id":"34","response_id":2}',
'{"tag_id":"4","response_id":1,"other":4}',
'{"tag_id":"34"}'),stringsAsFactors=F)
Le résultat souhaité, qui ne se réfère pas à la "autre" variable:
tag_id response_id
1 "34" 2
2 "4" 1
3 "34" NA
J'ai essayé plusieurs versions de:
parseLog <- function(x){
if (is.na(x))
e=c(tag_id=NA,response_id=NA)
else{
j=fromJSON(x)
e=c(tag_id=as.integer(j$tag_id),response_id=j$response_id)
}
e
}
qui semble bien fonctionner pour récupérer une liste de vecteurs (ou des listes si c est remplacé par list) mais quand j'essaye de convertir la liste en data.table, quelque chose ne fonctionne pas comme prévu.
parsed<-lapply(df$a,parseLog)
rparsed<-do.call(rbind.data.frame,parsed)
colnames(rparsed)<-c("tag_id","response_id")
En raison de la valeur manquante dans la troisième rangée. Comment puis-je le résoudre d'une manière propre? Comment puis-je faire que ma méthode parse retourne un NA pour la valeur manquante. Alternative, Y at-il un paramètre "fill" comme pour rbind qui peut être utilisé dans rbind.data.frame ou une méthode analogue?
L'ensemble de données que j'utilise a des lignes de 11M, donc la performance est importante.
De plus, il existe une méthode équivalente à rbind.data.frame pour obtenir une table de données. Comment cela serait-il utilisé? Quand je vérifie la documentation, il me renvoie à rbindlist mais il se plaint le paramètre est utilisé et si appel directement (sans do.call il se plaint du type de analysable):
rparsed<-do.call(rbindlist,fill=T,parsed)
EDIT: Le cas que je dois couverture est plus générale, dans un ensemble de 11M enregistre toutes les circonstances possibles se produisent:
df<-data.table(a=c('{"tag_id":"34","response_id":2}',
'{"trash":"34","useless":2}',
'{"tag_id":"4","response_id":1,"other":4}',
NA,
'{"response_id":"34"}',
'{"tag_id":"34"}'),stringsAsFactors=F)
et la sortie ne doit contenir que des colonnes tag_id et rESPONSE_ID.
J'ai édité mon exemple un peu comme je vois que, dans le but de résumant je n'ai pas inclus certaines données pertinentes. J'ai des variables supplémentaires dans le json qui ne m'intéresse pas ... beaucoup d'entre eux. Excellente réponse cependant! – Picarus
Mise à jour de la réponse. – LyzandeR
Néanmoins, la solution ne considère pas que le nombre de variables à ignorer est élevé, ce qui signifie que la trame de données qui peut être générée peut être énorme. Y a-t-il un moyen d'éviter cela? Peut-être ajouter les colonnes qui sont pertinentes un par un? L'ordre des variables est-il garanti dans la colonne json? Même si toute la colonne "json" que vous utilisez comme étape intermédiaire nécessitera beaucoup de mémoire. Je sais que je suis difficile, essayant juste de couvrir tous les problèmes possibles. – Picarus