데이터 소스

개요

OJS에서 데이터를 사용할 수 있게 하는 방법은 매우 다양합니다.

  • FileAttachments API로 CSV, JSON, SQLite 등을 읽습니다.

  • ojs_define() 함수를 사용해 Python이나 R에서 처리한 데이터를 {ojs} 셀에서 사용할 수 있게 합니다.

  • 온라인 서비스와 데이터 저장소를 위한 웹 API를 호출합니다.

아래에서 이 모든 기법을 살펴봅니다.

파일 첨부

표준 라이브러리의 FileAttachment 함수를 사용해 파일에서 데이터를 읽을 수 있습니다. 예를 들어, 여기서는 마우나로아의 NOAA 월별 CO2 농도 데이터 CSV를 읽어 그래프로 그립니다.

```{ojs}
data = {
  const co2data = await FileAttachment("co2_mm.csv")
    .csv({ typed: true } );
  return co2data.map(d => { 
    d["decimal date"] = Number(d["decimal date"]);
    d.average = Number(d.average); 
    return d; 
  });
}
Plot.plot({
  marks: [
    Plot.line(data, 
      { x: "decimal date", y: "average"}, 
      { stroke: "black" }
    )
  ]
})
```

여기서는 csv() 함수에 typed: true 옵션을 지정했습니다. 이 옵션을 지정하면 d3.autoType이 숫자, 날짜 등을 자동으로 감지해 올바른 JavaScript 타입으로 변환합니다. 데이터가 자동 타입 감지와 호환됨을 알고 있다면 강력히 권장됩니다.

구조화된 데이터 형식에 사용할 수 있는 메서드는 다음과 같습니다.

메서드 설명
csv 쉼표로 구분된 값
tsv 탭으로 구분된 값
json JSON (JavaScript 객체)
sqlite SQLite 데이터베이스 클라이언트
arrow Apache Arrow IPC 파일(압축 없음)

원시 데이터를 blob, text, image, stream으로 가져오는 메서드도 있습니다.

arrow() 메서드를 사용할 경우 Apache Arrow IPC 파일(Feather V2 파일)은 압축하지 않고 작성해야 합니다. 예를 들면 다음과 같습니다.

```{r}
arrow::write_feather(
  mtcars, 
  "data.arrow", 
  compression = "uncompressed"
)
```

```{ojs}
data = FileAttachment("data.arrow").arrow()
```

Python과 R

OJS에서 사용할 데이터가 항상 원시 형태로 사용 가능하지는 않습니다. 종종 Python이나 R로 원시 데이터를 읽고 전처리해야 합니다. 이 전처리는 문서 렌더링 과정에서({r} 또는 {python} 코드 셀에서) 수행하고, ojs_define() 함수를 통해 {ojs} 셀에서 사용할 수 있게 만들 수 있습니다.

예를 들어, 같은 데이터를 R에서 읽어 그룹화와 요약을 수행한 뒤 ojs_define을 사용해 OJS에서 사용할 수 있도록 합니다.

```{r}
#| output: false

library(readr)
library(dplyr)

co2 = read_csv("co2_mm.csv")  %>% 
  group_by(year) %>% 
  summarize(max = max(average))

ojs_define(co2data = co2)
```

같은 작업을 Python으로도 할 수 있습니다(ojs_define 함수는 R이나 Python을 사용하는 어떤 문서에서도 사용할 수 있습니다).

이제 Observable Plot으로 데이터를 그립니다.

```{ojs}
yearlyChart = Plot.plot({
  marks: [
    Plot.line(transpose(co2data), 
      {x: "year", y: "max"}, 
      { stroke: "black" }
    )
  ]}
)
```

NOAA C02 예제에서 전체 소스 코드를 확인하세요.

전치(Transpose)

위의 OJS 코드에는 한 가지 추가적인 포인트가 있습니다. 바로 그래프를 그리기 전에 co2datatranspose 함수를 호출하는 것입니다. transpose 함수는 Quarto의 OJS 엔진에 내장되어 있으며, Python과 R에서 사용하는 열 지향 데이터셋을 많은 JavaScript 플로팅 라이브러리(Plot 포함)에서 사용하는 행 지향 데이터셋으로 변환합니다.

예를 들어 R이나 Python에서 다음과 같은 JSON 데이터가 나왔다고 하면,

{
  "year": [1958, 1959, 1960],
  "max":  [317.51, 318.29, 320.04]
}

transpose 호출을 통해 다음과 같이 변환됩니다.

[
  { "year": 1959, "max": 317.51 },
  { "year": 1960, "max": 318.29 },
  { "year": 1960, "max": 320.04 }
]

OJS에서 사용하는 플로팅 라이브러리의 문서를 확인해 transpose 호출이 필요한지 확인하세요.

웹 API

d3.json() 함수를 사용하면 웹 서비스와 데이터 소스에서 JSON 데이터를 읽을 수 있습니다. 여기서는 GitHub API를 호출해 Python pandas 패키지의 기여 데이터를 가져옵니다.

```{ojs}
d3 = require('d3')

contributors = await d3.json(
  "https://api.github.com/repos/pandas-dev/pandas/stats/contributors"
)

commits = contributors.map(contributor => {
  const author = contributor.author;
  return {
    name: author.login,
    title: author.login,
    group: author.type,
    value: contributor.total
  }
})
```

커밋 수 기준으로 정렬된 데이터를 확인합니다.

```{ojs}
Inputs.table(commits, { sort: "value", reverse: true })
```

GitHub API 예제에서 전체 소스 코드를 확인하세요.