0Pricing
R Academy · Pelajaran

Menangani Struktur JSON Bertingkat

Ratakan JSON yang bertingkat secara mendalam menjadi kerangka data rapi untuk analisis.

Menangani Struktur JSON Bertingkat adalah pelajaran R Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar R Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus R Academy mencakup 4 pelajaran total.

Mengapa JSON Bertingkat Itu Sulit

API REST sering mengembalikan JSON yang sangat bertingkat, sehingga satu bidang dapat berisi array objek yang kemudian masih berisi objek lain. Meratakan struktur ini menjadi kerangka data rapi memerlukan pemahaman tentang cara kerja jsonlite, purrr, dan tidyr secara bersama-sama.

# Example nested JSON from a REST API:
json_str <- '{
  "user": {
    "id": 1,
    "name": "Alice",
    "orders": [
      {"order_id": 101, "total": 59.99, "status": "shipped"},
      {"order_id": 102, "total": 24.50, "status": "pending"}
    ]
  }
}'

# The challenge: 'orders' is an array of objects inside 'user'
cat('Nested JSON loaded as string, length:', nchar(json_str))

fromJSON() — Penguraian Dasar

jsonlite::fromJSON() mengonversi string JSON atau jalur file menjadi objek R. JSON datar sederhana menjadi daftar atau kerangka data. JSON bertingkat menjadi daftar bertingkat — array objek menjadi kerangka data yang disimpan di dalam kolom daftar.

library(jsonlite)

# Parse flat JSON
flat_json <- '{"name": "Alice", "age": 30, "score": 95.5}'
result <- fromJSON(flat_json)
cat('Name:', result$name, '\n')
cat('Age: ', result$age,  '\n')

# Parse an array of objects — becomes a data frame
array_json <- '[{"id":1,"val":10},{"id":2,"val":20},{"id":3,"val":30}]'
df <- fromJSON(array_json)
cat('Class:', class(df), '\n')
print(df)

fromJSON() dengan flatten = TRUE

Argumen flatten = TRUE memberi tahu fromJSON() untuk membongkar kerangka data bertingkat secara rekursif menjadi kolom dengan nama yang dipisahkan titik. Cara ini berfungsi baik untuk satu tingkat penyarangan dan merupakan cara tercepat untuk menangani JSON yang cukup bertingkat.

library(jsonlite)

json_str <- '[{
  "id": 1,
  "name": "Alice",
  "address": {"city": "Berlin", "country": "Germany"}
},{
  "id": 2,
  "name": "Bob",
  "address": {"city": "Paris", "country": "France"}
}]'

# Without flatten:
nested_df <- fromJSON(json_str, flatten = FALSE)
cat('address class:', class(nested_df$address), '\n')

# With flatten = TRUE:
flat_df <- fromJSON(json_str, flatten = TRUE)
cat('Columns:', names(flat_df), '\n')
print(flat_df)

Array Bertingkat Menjadi Kolom Daftar

Ketika suatu bidang JSON berisi array objek, fromJSON() menyimpannya sebagai kolom daftar dalam kerangka data — setiap sel berisi sebuah kerangka data. Anda harus mengakses atau meratakannya secara eksplisit.

library(jsonlite)

json_str <- '[{
  "user_id": 1,
  "tags": ["R", "Python", "SQL"]
},{
  "user_id": 2,
  "tags": ["Java", "Kotlin"]
}]'

df <- fromJSON(json_str)
cat('tags column class:', class(df$tags), '\n')

# Access tags for user 1:
cat('User 1 tags:', df$tags[[1]], '\n')
cat('User 2 tags:', df$tags[[2]])

purrr::map() — Mengekstrak Bidang Bertingkat

purrr::map() menerapkan fungsi pada setiap elemen daftar. Jika setiap elemen merupakan daftar bernama (objek JSON yang telah diurai), Anda dapat memberikan string untuk mengekstrak bidang bernama dari setiap elemen — pengganti perulangan yang ringkas.

library(jsonlite)
library(purrr)

json_str <- '[{
  "id": 1,
  "meta": {"score": 88, "grade": "B"}
},{
  "id": 2,
  "meta": {"score": 95, "grade": "A"}
},{
  "id": 3,
  "meta": {"score": 72, "grade": "C"}
}]'

records <- fromJSON(json_str, simplifyDataFrame = FALSE)

# Extract 'score' from each record's 'meta' object
scores <- map_dbl(records, function(r) r$meta$score)
grades <- map_chr(records, function(r) r$meta$grade)

cat('Scores:', scores, '\n')
cat('Grades:', grades)

purrr::map() dengan Pintasan String

purrr::map(list, 'field_name') adalah bentuk singkat untuk mengekstrak bidang bernama dari setiap elemen — setara dengan map(list, function(x) x[['field_name']]). Gunakan map_chr(), map_dbl(), dan sebagainya untuk mendapatkan vektor atomik bertipe, bukan daftar.

library(jsonlite)
library(purrr)

json_str <- '[{"name":"Alice","score":90},{"name":"Bob","score":78},{"name":"Carol","score":85}]'

# Parse as list of lists
records <- fromJSON(json_str, simplifyDataFrame = FALSE)

# String shortcut to extract field
names_vec  <- map_chr(records, 'name')
scores_vec <- map_dbl(records, 'score')

cat('Names: ', names_vec, '\n')
cat('Scores:', scores_vec, '\n')

# Build a clean data frame
clean_df <- data.frame(name = names_vec, score = scores_vec)
print(clean_df)

Penyarangan Mendalam dengan Rangkaian map()

Untuk JSON yang sangat bertingkat, rangkai beberapa pemanggilan map(). Setiap pemanggilan turun satu tingkat. Gunakan map(list, 'field') pada setiap tingkat dan terapkan map_*() bertipe pada langkah terdalam untuk mengekstrak nilai akhir.

library(jsonlite)
library(purrr)

json_str <- '[{
  "id": 1,
  "company": {"hq": {"city": "Berlin", "country": "Germany"}}
},{
  "id": 2,
  "company": {"hq": {"city": "Tokyo",  "country": "Japan"}}
}]'

records <- fromJSON(json_str, simplifyDataFrame = FALSE)

# Navigate: records -> company -> hq -> city
cities <- map_chr(records, function(r) r$company$hq$city)
cat('Cities:', cities, '\n')

# Or using nested map shortcut:
ids <- map_int(records, 'id')
cat('IDs:', ids)

tidyr::unnest() — Meratakan Kolom Daftar

tidyr::unnest() memperluas kolom daftar yang berisi kerangka data, dengan membuat satu baris untuk setiap elemen bertingkat. Ini adalah pendekatan rapi standar untuk meratakan hubungan satu-ke-banyak dalam data JSON.

library(jsonlite)
library(tidyr)
library(dplyr)

json_str <- '[{
  "user_id": 1,
  "orders": [{"oid":101,"total":50},{"oid":102,"total":30}]
},{
  "user_id": 2,
  "orders": [{"oid":103,"total":80}]
}]'

df <- fromJSON(json_str)
cat('Before unnest, rows:', nrow(df), '\n')
cat('orders class:', class(df$orders), '\n')

# Unnest expands one row per order
expanded <- unnest(df, cols = orders)
cat('After unnest, rows:', nrow(expanded), '\n')
print(expanded)

jsonlite::flatten() pada Kerangka Data

jsonlite::flatten() bekerja pada kerangka data yang sudah diurai (bukan string JSON), lalu memperluas kolom kerangka data bertingkat secara rekursif menjadi kolom nama yang dipisahkan titik. Fungsi ini berguna setelah fromJSON(..., flatten = FALSE) ketika Anda ingin melakukan perataan sebagai langkah pascapemrosesan.

library(jsonlite)

json_str <- '[{
  "id": 1,
  "profile": {"age": 25, "city": "Rome"}
},{
  "id": 2,
  "profile": {"age": 31, "city": "Oslo"}
}]'

# Parse without auto-flatten
nested <- fromJSON(json_str, flatten = FALSE)
cat('Columns before flatten:', names(nested), '\n')
cat('profile class:', class(nested$profile), '\n')

# Apply flatten() post-hoc
flat <- flatten(nested)
cat('Columns after flatten:', names(flat), '\n')
print(flat)

Menangani Nilai Null dalam JSON Bertingkat

Nilai JSON null diurai menjadi NULL dalam R, yang menimbulkan masalah saat membuat kerangka data — NULL dalam daftar akan menghapus elemen tersebut sepenuhnya. Gunakan purrr::map() dengan argumen .default atau %||% untuk mengganti nilai yang hilang dengan aman.

library(jsonlite)
library(purrr)

json_str <- '[{"id":1,"email":"alice@example.com"},{"id":2,"email":null},{"id":3,"email":"carol@example.com"}]'

records <- fromJSON(json_str, simplifyDataFrame = FALSE)

# Unsafe: NULL drops the element
# emails <- map_chr(records, 'email')  # ERROR on null

# Safe: provide a default for missing values
emails <- map_chr(records, function(r) {
  if (is.null(r$email)) NA_character_ else r$email
})

cat('Emails:', emails)
cat('NAs:', sum(is.na(emails)))

Pipeline Lengkap: JSON API menjadi Kerangka Data Rapi

Menggabungkan semuanya: pipeline realistis yang mengurai JSON bertingkat dari API, mengekstrak bidang dengan purrr, menangani nilai null, dan menghasilkan kerangka data rapi yang siap dianalisis.

library(jsonlite)
library(purrr)
library(dplyr)

# Simulated API response
api_json <- '[{
  "id": 1, "name": "Alice",
  "stats": {"score": 92, "rank": 1}
},{
  "id": 2, "name": "Bob",
  "stats": null
},{
  "id": 3, "name": "Carol",
  "stats": {"score": 85, "rank": 3}
}]'

records <- fromJSON(api_json, simplifyDataFrame = FALSE)

result <- tibble(
  id    = map_int(records,  'id'),
  name  = map_chr(records,  'name'),
  score = map_dbl(records,  function(r) if (is.null(r$stats)) NA_real_ else r$stats$score),
  rank  = map_int(records,  function(r) if (is.null(r$stats)) NA_integer_ else r$stats$rank)
)

print(result)

Pemeriksaan Singkat

Anda memiliki kerangka data df dengan kolom orders berupa kolom daftar yang berisi kerangka data (satu untuk setiap pengguna). Fungsi apa yang memperluasnya menjadi satu baris untuk setiap pesanan?

JSON Bertingkat — Inti Pembelajaran

Penanganan JSON bertingkat di R memerlukan seperangkat alat berlapis:

  • fromJSON(json, flatten = TRUE) — meratakan satu tingkat struktur bertingkat secara otomatis
  • fromJSON(json, simplifyDataFrame = FALSE) — memperoleh daftar berisi daftar untuk pemrosesan manual
  • Array bertingkat → kolom-daftar pada kerangka data yang dihasilkan
  • purrr::map_chr/dbl/int(list, 'field') — mengekstrak nilai bertipe dari setiap elemen
  • Panggilan map() berantai menelusuri tingkat struktur bertingkat yang dalam
  • tidyr::unnest(df, cols = col) — memperluas kolom-daftar yang berisi kerangka data
  • jsonlite::flatten(df) — meratakan kolom kerangka data bertingkat setelah penguraian
  • Selalu tangani NULL dengan if (is.null(x)) NA else x
library(jsonlite)
library(purrr)

# Quick reference:
json <- '[{"id":1,"info":{"val":10}},{"id":2,"info":null}]'
recs <- fromJSON(json, simplifyDataFrame = FALSE)

# Safe extraction with null guard
vals <- map_dbl(recs, function(r) {
  if (is.null(r$info)) NA_real_ else r$info$val
})

result <- data.frame(id = map_int(recs, 'id'), val = vals)
print(result)

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menangani Struktur JSON Bertingkat” gratis?

Ya — teks lengkap “Menangani Struktur JSON Bertingkat” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus R Academy, upgrade ke CoddyKit PRO. Kursus R Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menangani Struktur JSON Bertingkat”?

Ratakan JSON yang bertingkat secara mendalam menjadi kerangka data rapi untuk analisis. Kamu berlatih R Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai R Academy?

Tidak diperlukan pengalaman sebelumnya. R Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Menangani Struktur JSON Bertingkat” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran R Academy ini?

Ya. Setiap pelajaran R Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengurai JSON dengan jsonlite
  2. Membuat Permintaan HTTP dengan httr2
  3. Menggunakan API REST di R
  4. Menangani Struktur JSON Bertingkat
← Kembali ke R Academy