Obtendo dados json importados em um quadro de dados

Eu tenho um arquivo contendo mais de 1500 objects json com os quais eu quero trabalhar em R. Eu pude importar os dados como uma lista, mas estou tendo problemas para coagi-los em uma estrutura útil. Eu quero criar um quadro de dados contendo uma linha para cada object json e uma coluna para cada par chave: valor.

Eu recriou minha situação com este pequeno e falso dataset:

[{"name":"Doe, John","group":"Red","age (y)":24,"height (cm)":182,"wieght (kg)":74.8,"score":null}, {"name":"Doe, Jane","group":"Green","age (y)":30,"height (cm)":170,"wieght (kg)":70.1,"score":500}, {"name":"Smith, Joan","group":"Yellow","age (y)":41,"height (cm)":169,"wieght (kg)":60,"score":null}, {"name":"Brown, Sam","group":"Green","age (y)":22,"height (cm)":183,"wieght (kg)":75,"score":865}, {"name":"Jones, Larry","group":"Green","age (y)":31,"height (cm)":178,"wieght (kg)":83.9,"score":221}, {"name":"Murray, Seth","group":"Red","age (y)":35,"height (cm)":172,"wieght (kg)":76.2,"score":413}, {"name":"Doe, Jane","group":"Yellow","age (y)":22,"height (cm)":164,"wieght (kg)":68,"score":902}] 

Algumas características dos dados:

  • Todos os objects contêm o mesmo número de pares chave: valor, embora alguns dos valores sejam nulos
  • Existem duas colunas não numéricas por object (nome e grupo)
  • nome é o identificador único, existem 10 ou mais grupos
  • muitos dos nomes e grupos incluem espaços, vírgulas e outras pontuações.

Com base nesta pergunta: R list (structure (list () ())) para frame de dados , tentei o seguinte:

 json_file <- "test.json" json_data <- fromJSON(json_file) asFrame <- do.call("rbind.fill", lapply(json_data, as.data.frame)) 

Com meus dados reais e esses dados falsos, a última linha me deu este erro:

 Error in data.frame(name = "Doe, John", group = "Red", `age (y)` = 24, : arguments imply differing number of rows: 1, 0 

Você só precisa replace seus NULLs por NAs:

 require(RJSONIO) json_file <- '[{"name":"Doe, John","group":"Red","age (y)":24,"height (cm)":182,"wieght (kg)":74.8,"score":null}, {"name":"Doe, Jane","group":"Green","age (y)":30,"height (cm)":170,"wieght (kg)":70.1,"score":500}, {"name":"Smith, Joan","group":"Yellow","age (y)":41,"height (cm)":169,"wieght (kg)":60,"score":null}, {"name":"Brown, Sam","group":"Green","age (y)":22,"height (cm)":183,"wieght (kg)":75,"score":865}, {"name":"Jones, Larry","group":"Green","age (y)":31,"height (cm)":178,"wieght (kg)":83.9,"score":221}, {"name":"Murray, Seth","group":"Red","age (y)":35,"height (cm)":172,"wieght (kg)":76.2,"score":413}, {"name":"Doe, Jane","group":"Yellow","age (y)":22,"height (cm)":164,"wieght (kg)":68,"score":902}]' json_file <- fromJSON(json_file) json_file <- lapply(json_file, function(x) { x[sapply(x, is.null)] <- NA unlist(x) }) 

Quando você tiver um valor não nulo para cada elemento, poderá chamar o rbind sem receber um erro:

 do.call("rbind", json_file) name group age (y) height (cm) wieght (kg) score [1,] "Doe, John" "Red" "24" "182" "74.8" NA [2,] "Doe, Jane" "Green" "30" "170" "70.1" "500" [3,] "Smith, Joan" "Yellow" "41" "169" "60" NA [4,] "Brown, Sam" "Green" "22" "183" "75" "865" [5,] "Jones, Larry" "Green" "31" "178" "83.9" "221" [6,] "Murray, Seth" "Red" "35" "172" "76.2" "413" [7,] "Doe, Jane" "Yellow" "22" "164" "68" "902" 

Isto é muito simples se você usar library(jsonlite) e a function fromJSON . Também manipula os valores null e os converte em NA .

 json_file <- '[{"name":"Doe, John","group":"Red","age (y)":24,"height (cm)":182,"wieght (kg)":74.8,"score":null}, {"name":"Doe, Jane","group":"Green","age (y)":30,"height (cm)":170,"wieght (kg)":70.1,"score":500}, {"name":"Smith, Joan","group":"Yellow","age (y)":41,"height (cm)":169,"wieght (kg)":60,"score":null}, {"name":"Brown, Sam","group":"Green","age (y)":22,"height (cm)":183,"wieght (kg)":75,"score":865}, {"name":"Jones, Larry","group":"Green","age (y)":31,"height (cm)":178,"wieght (kg)":83.9,"score":221}, {"name":"Murray, Seth","group":"Red","age (y)":35,"height (cm)":172,"wieght (kg)":76.2,"score":413}, {"name":"Doe, Jane","group":"Yellow","age (y)":22,"height (cm)":164,"wieght (kg)":68,"score":902}]' library(jsonlite) fromJSON(json_file) # name group age (y) height (cm) wieght (kg) score # 1 Doe, John Red 24 182 74.8 NA # 2 Doe, Jane Green 30 170 70.1 500 # 3 Smith, Joan Yellow 41 169 60.0 NA # 4 Brown, Sam Green 22 183 75.0 865 # 5 Jones, Larry Green 31 178 83.9 221 # 6 Murray, Seth Red 35 172 76.2 413 # 7 Doe, Jane Yellow 22 164 68.0 902 str(fromJSON(json_file)) # 'data.frame': 7 obs. of 6 variables: # $ name : chr "Doe, John" "Doe, Jane" "Smith, Joan" "Brown, Sam" ... # $ group : chr "Red" "Green" "Yellow" "Green" ... # $ age (y) : int 24 30 41 22 31 35 22 # $ height (cm): int 182 170 169 183 178 172 164 # $ wieght (kg): num 74.8 70.1 60 75 83.9 76.2 68 # $ score : int NA 500 NA 865 221 413 902 
 library(rjson) Lines <- readLines("yelp_academic_dataset_business.json") business <- as.data.frame(t(sapply(Lines, fromJSON))) 

Você pode tentar isso para carregar dados JSON em R

 dplyr::bind_rows(fromJSON(file_name)) 

Para remover valores nulos, use o parâmetro nullValue

 json_data <- fromJSON(json_file, nullValue = NA) asFrame <- do.call("rbind.fill", lapply(json_data, as.data.frame)) 

Desta forma, não haverá cotações desnecessárias em sua saída