Rで解析:CDISC準拠のAnalysis Results Data(ARD)を構築する「cards」パッケージの紹介
医療やライフサイエンス分野では、臨床試験や研究の結果を正しく記録し共有することが重要です。膨大なデータを分析し、意味のある知見を得るためには、データの整理と可視化が必要不可欠です。本パッケージは臨床試験の結果を交換・再利用可能な形式に変換するだけでなく、サマリーテーブルやビジュアライゼーションを作成し、レポートを生成することができます。
なお、CDISCはClinical Data Interchange Standards Consortiumの略で、臨床試験データの交換や保存のための標準規格を定めている団体です。
CDISC | Clear Data. Clear Impact.
パッケージバージョンは0.8.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
<おすすめのRに関する書籍です>
医学研究のためのRによる統計解析入門
論文執筆や学会発表のための統計解析手法が、しっかり身に付く!
著者: 加葉田 大志朗, 新谷 歩
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("cards")
# パッケージの読み込み
library("cards")
# コマンド例で必要なパッケージ
# install.packages("tidyverse")
library("tidyverse")スポンサーリンク
コマンド例
詳細はコメント、パッケージのヘルプを確認してください。
ネストされたリストを結果データフレームの列に展開:.process_nested_list_as_dfコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| x | 結果データフレーム | |
| arg | ネストされたリスト | |
| new_column | 新しい列名を指定する | |
| unlist | 完全な結果を解除するかどうか | FALSE |
# ADSLのデータを集計し、AGEGR1でグループ化する
ard <- ard_tabulate(ADSL, by = "ARM", variables = "AGEGR1")
# ネストされたリストを新しい列に展開する処理を行う
cards:::.process_nested_list_as_df(ard, NULL, "new_col")実行結果:
group1 group1_level variable variable_level stat_name stat_label stat
1 ARM Placebo AGEGR1 <65 n n 14
2 ARM Placebo AGEGR1 <65 N N 86
3 ARM Placebo AGEGR1 <65 p % 0.163
4 ARM Placebo AGEGR1 >80 n n 30
5 ARM Placebo AGEGR1 >80 N N 86
6 ARM Placebo AGEGR1 >80 p % 0.349
7 ARM Placebo AGEGR1 65-80 n n 42
8 ARM Placebo AGEGR1 65-80 N N 86
9 ARM Placebo AGEGR1 65-80 p % 0.488
10 ARM Xanomeli… AGEGR1 <65 n n 11特定の変数にラベルを付与:ard_attributesコマンド
この関数を使用する場面では、データの特徴量や属性を理解し、分析や可視化の前処理として役立ちます。
| オプション | 意味 | 初期値 |
|---|---|---|
| data | (data.frame) データフレーム | |
| variables | (tidy-select) 含める変数を指定 | |
| label | (named list) 変数ラベルを指定する名付けたリスト |
# サンプルデータフレームを作成
df <- tibble(var1 = letters, var2 = LETTERS)
# var1列にラベル属性を設定
attr(df$var1, "label") <- "Lowercase Letters"
# 全ての変数の属性を取得
ard_attributes(df, variables = everything())実行結果:
variable context stat_name stat_label stat fmt_fun
1 var1 attribut… label Variable… Lowercas… <fn>
2 var1 attribut… class Variable… character NULL
3 var2 attribut… label Variable… var2 <fn>
4 var2 attribut… class Variable… character NULL階層的にネストされたタブレーションを実行:ard_hierarchical・ard_hierarchical_countコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| data | (data.frame) データフレーム | |
| variables | (tidy-select) 階層的(ネスト)集計を行う変数を指定 | |
| by | (tidy-select) 集計の区分に使う変数を指定 | グループ化された変数 |
| statistic | (formula-list-selector) 形式のリストや単一の形式で、指定された要素が「n」、「N」、「p」、「n_cum」、「p_cum」のいずれかである場合 | |
| denominator | (data.frame, integer) データフレームを使用して出力結果を定義し、分母を指定する。ard_hierarchical()では必須の引数、ard_hierarchical_count()では任意 | |
| fmt_fun | (formula-list-selector) 形式のリストや単一の形式で、指定された要素が名付けたリストの関数である場合 | |
| stat_label | (formula-list-selector) 形式のリストや単一の形式で、指定された要素が統計ラベルを定義する名付けたリストや形式のリストである場合 | |
| id | (tidy-select) オプションの引数で、c(id, variables)列の組み合わせに重複がないことを確認する | |
| fmt_fn | 非推奨の引数(fmt_funを使用) |
# AESOC内でAEDECODを階層的に集計する(被験者ごとの最終レコードのみを使用)
ard_hierarchical(
data = ADAE |>
dplyr::slice_tail(n = 1L, by = c(USUBJID, TRTA, AESOC, AEDECOD)),
variables = c(AESOC, AEDECOD),
by = TRTA,
id = USUBJID,
denominator = ADSL
)
# AESOC・AEDECODの両方の階層について件数を集計する
ard_hierarchical_count(
data = ADAE,
variables = c(AESOC, AEDECOD),
by = TRTA
)実行結果:
group1 group1_level group2 group2_level variable variable_level stat_name stat_label stat
1 TRTA Placebo AESOC CARDIAC … AEDECOD ATRIAL F… n n 1
2 TRTA Placebo AESOC CARDIAC … AEDECOD ATRIAL F… n n 0
3 TRTA Placebo AESOC CARDIAC … AEDECOD ATRIAL H… n n 2
4 TRTA Placebo AESOC CARDIAC … AEDECOD ATRIOVEN… n n 1
5 TRTA Placebo AESOC CARDIAC … AEDECOD ATRIOVEN… n n 2
6 TRTA Placebo AESOC CARDIAC … AEDECOD BRADYCAR… n n 4
7 TRTA Placebo AESOC CARDIAC … AEDECOD BUNDLE B… n n 1
8 TRTA Placebo AESOC CARDIAC … AEDECOD BUNDLE B… n n 2
9 TRTA Placebo AESOC CARDIAC … AEDECOD CARDIAC … n n 0
10 TRTA Placebo AESOC CARDIAC … AEDECOD CARDIAC … n n 1
…(以下略)
<おすすめのRに関する書籍です>
はじめてのR: ごく初歩の操作から統計解析の導入まで | 村井 潤一郎
Amazonで村井 潤一郎のはじめてのR: ごく初歩の操作から統計解析の導入まで。
複数の変数の統計量をまとめて計算:ard_mvsummaryコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| data | (data.frame) データフレーム | |
| variables | 要約する列の選択 | |
| by | 集計の区分に使う列を指定;未観測の組み合わせ・因子水準も含めた全ての組み合わせについて結果が計算される | |
| strata | 集計の層別に使う列を指定;byと併用可能。実際に観測された組み合わせについてのみ結果が計算される | NULL |
| statistic | 統計量を計算する関数を指定;関数はx、data、full_data、by、strataを引数として受け取れるよう定義する(”…”を含めることを推奨) | |
| fmt_fun | (formula-list-selector) 形式のリストや単一の形式で、指定された要素が名付けたリストの関数である場合 | |
| stat_label | 統計ラベルを定義する式のリスト | |
| fmt_fn | 非推奨の引数(fmt_funを使用) |
# ard_summary()と同じ挙動を再現する例
ard_mvsummary(
ADSL,
by = "ARM",
variables = "AGE",
statistic = list(AGE = list(mean = \(x, ...) mean(x)))
)
# グループ内平均と全体平均の両方を返す関数を定義
grand_mean <- function(data, full_data, variable, ...) {
list(
mean = mean(data[[variable]], na.rm = TRUE),
grand_mean = mean(full_data[[variable]], na.rm = TRUE)
)
}
# ARMでグループ化し、グループ内平均と全体平均を計算する
ADSL |>
dplyr::group_by(ARM) |>
ard_mvsummary(
variables = "AGE",
statistic = list(AGE = list(means = grand_mean))
)実行結果:
group1 group1_level variable stat_name stat_label stat
1 ARM Placebo AGE mean Mean 75.209
2 ARM Xanomeli… AGE mean Mean 74.381
3 ARM Xanomeli… AGE mean Mean 75.667
group1 group1_level variable stat_name stat_label stat
1 ARM Placebo AGE mean Mean 75.209
2 ARM Placebo AGE grand_mean grand_me… 75.087
3 ARM Xanomeli… AGE mean Mean 74.381
4 ARM Xanomeli… AGE grand_mean grand_me… 75.087
5 ARM Xanomeli… AGE mean Mean 75.667
6 ARM Xanomeli… AGE grand_mean grand_me… 75.087エラー発生時もARDの構造を保つ関数ラッパーを作成:as_cards_fnコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| f | 関数の指定 | |
| stat_names | 期待される統計名の指定 |
# エラーが起きない場合、as_cards_fn()を使わない場合と同じ結果になる
ttest_works <-
as_cards_fn(
\(x) t.test(x)[c("statistic", "p.value")],
stat_names = c("statistic", "p.value")
)
ard_summary(
mtcars,
variables = mpg,
statistic = ~ list(ttest = ttest_works)
)
# エラーが発生してもas_cards_fn()を使っていれば、
# エラーが起きなかった場合と同じ構造の結果が得られる
ttest_error <-
as_cards_fn(
\(x) {
t.test(x)[c("statistic", "p.value")]
stop("Intentional Error")
},
stat_names = c("statistic", "p.value")
)
ard_summary(
mtcars,
variables = mpg,
statistic = ~ list(ttest = ttest_error)
)
# as_cards_fn()を使わずにエラーが発生した場合、
# 返される結果は1行のみになる
ard_summary(
mtcars,
variables = mpg,
statistic = ~ list(ttest = \(x) {
t.test(x)[c("statistic", "p.value")]
stop("Intentional Error")
})
)実行結果:
variable context stat_name stat_label stat fmt_fun
1 mpg summary statistic statistic 18.857 1
2 mpg summary p.value p.value 0 1
variable context stat_name stat_label stat error
1 mpg summary statistic statistic Intentio…
2 mpg summary p.value p.value Intentio…
variable context stat_name stat_label stat error
1 mpg summary ttest ttest Intentio…非推奨関数shuffle_ard()でARDオブジェクトを整理する:shuffle_ardコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| x | ARDデータフレームの指定 | |
| trim | 統計値のメタデータを削除し、数値の統計量のみに絞り込むかどうかの指定 | TRUE |
# 2つのARDを結合する
bind_ard(
ard_tabulate(ADSL, by = "ARM", variables = "AGEGR1"),
ard_tabulate(ADSL, variables = "ARM")
) |>
# 結合したARDを整理する(非推奨関数)
shuffle_ard()実行結果:
# A tibble: 36 × 7
ARM variable variable_level context stat_name stat_label stat
<chr> <chr> <chr> <chr> <chr> <chr> <dbl>
1 Placebo AGEGR1 <65 tabula… n n 14
2 Placebo AGEGR1 <65 tabula… N N 86
3 Placebo AGEGR1 <65 tabula… p % 0.163
4 Placebo AGEGR1 >80 tabula… n n 30
5 Placebo AGEGR1 >80 tabula… N N 86
6 Placebo AGEGR1 >80 tabula… p % 0.349
7 Placebo AGEGR1 65-80 tabula… n n 42
8 Placebo AGEGR1 65-80 tabula… N N 86
9 Placebo AGEGR1 65-80 tabula… p % 0.488
10 Xanomeline High … AGEGR1 <65 tabula… n n 11
# ℹ 26 more rows
n・N・pなどのタブレーション統計量を計算:.calculate_tabulation_statisticsコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| data | (data.frame) データフレーム | |
| variables | 要約する列の選択 | everything() |
| by | 集計の区分に使う列を指定;未観測の組み合わせ・因子水準も含めた全ての組み合わせについて集計される | |
| strata | 集計の層別に使う列を指定;byと併用可能。実際に観測された組み合わせについてのみ集計される | |
| denominator | 分母を変更するための引数。例えば「N」統計量の算出方法を指定する | ‘column’ |
| statistic | (formula-list-selector) 形式のリストや単一の形式で、指定された要素が「n」、「N」、「p」、「n_cum」、「p_cum」のいずれかである場合 |
# ARM列の件数(N)をタブレーション統計として計算する
cards:::.calculate_tabulation_statistics(
ADSL,
variables = "ARM",
by = NULL,
strata = NULL,
denominator = "cell",
statistic = list(ARM = list(tabulation = c("N")))
)実行結果:
# A tibble: 3 × 6
variable variable_level stat_name stat warning error
<chr> <list> <chr> <list> <list> <list>
1 ARM <chr [1]> N <int [1]> <NULL> <NULL>
2 ARM <chr [1]> N <int [1]> <NULL> <NULL>
3 ARM <chr [1]> N <int [1]> <NULL> <NULL>「..cards_overall..」等のプレースホルダーを表示用ラベルに変換:.derive_overall_labelsコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| x | 対象の現在の列内容 | |
| cur_col | 現在の列名 | dplyr::cur_column() |
# プレースホルダーを含むサンプルデータを作成
data <- dplyr::tibble(
ARM = c("..cards_overall..", "Overall ARM", NA, "BB", NA),
TRTA = c(NA, NA, "..hierarchical_overall..", "C", "C")
)
# 各列のプレースホルダーを表示用ラベルに変換する
data |>
dplyr::mutate(
dplyr::across(
ARM:TRTA,
cards:::.derive_overall_labels
)
)実行結果:
# A tibble: 5 × 2
ARM TRTA
<chr> <chr>
1 Overall ARM.1 <NA>
2 Overall ARM <NA>
3 <NA> Any TRTA
4 BB C
5 <NA> C
この記事が誰かの役に立ちますように。
スポンサーリンク