バイオインフォマティクスでは、大量のデータを効率的に処理し、解析することが求められます。R の tidyverse パッケージは、そのようなデータ処理に非常に有用なツールを提供しています。本記事では、dplyr::across()
に焦点を当て、その基本から応用までを解説します。
1. across() とは?
1.1 across() の概要
across()
は、dplyr
1.0.0 で導入された関数で、複数の列に対して一括で操作を適用できる機能を持っています。従来の mutate()
や summarise()
で列ごとに関数を適用する際のコードを簡潔に記述できるため、特に大規模データ処理での利便性が向上しました。
1.2 基本的な使い方
across()
は mutate()
や summarise()
の中で使用され、複数の列に対して同じ関数を適用することができます。
library(tidyverse)
# サンプルデータ
df <- tibble(
sample_id = c("S1", "S2", "S3"),
gene_A = c(10, 15, 20),
gene_B = c(5, 10, 15),
gene_C = c(3, 6, 9)
)
# すべての数値列を2倍にする
df %>%
mutate(across(where(is.numeric), ~ . * 2))
出力:
# A tibble: 3 × 4
sample_id gene_A gene_B gene_C
<chr> <dbl> <dbl> <dbl>
1 S1 20 10 6
2 S2 30 20 12
3 S3 40 30 18
ここでは where(is.numeric)
を使って、数値列に限定して * 2
の計算を適用しました。
2. across() の応用
2.1 特定の列のみを選択
バイオインフォマティクスのデータでは、特定の遺伝子の発現データのみ処理することが多くあります。特定の列を選択する場合、c()
を使用できます。
df %>%
mutate(across(c(gene_A, gene_B), log2))
出力:
# A tibble: 3 × 4
sample_id gene_A gene_B gene_C
<chr> <dbl> <dbl> <dbl>
1 S1 3.32 2.32 3
2 S2 3.91 3.32 6
3 S3 4.32 3.91 9
ここでは gene_A
と gene_B
のみを選択し、それぞれ対数変換 (log2()
) を適用しました。
2.2 複数の関数を適用
複数の関数を適用する場合、リスト list()
を使うと、異なる統計量をまとめて計算できます。
df %>%
summarise(across(c(gene_A, gene_B), list(mean = mean, sd = sd)))
出力:
# A tibble: 1 × 4
gene_A_mean gene_A_sd gene_B_mean gene_B_sd
<dbl> <dbl> <dbl> <dbl>
1 15 5.00 10 5.00
このように mean()
や sd()
を適用することで、各遺伝子の平均値と標準偏差を計算できます。
2.3 条件付きで処理
特定の条件を満たす列だけを選択し、異なる操作を適用することも可能です。
df %>%
mutate(across(where(~ is.numeric(.) && mean(., na.rm = TRUE) > 10), log2))
この例では、平均値が10を超える列のみ log2()
を適用します。
3. バイオインフォマティクスでの実用例
3.1 正規化(Zスコア変換)
RNA-seq の発現データを正規化する際には、各遺伝子の Z スコアを計算することが一般的です。
df %>%
mutate(across(where(is.numeric), ~ (. - mean(.)) / sd(.)))
このコードでは、全数値列に対して (値 - 平均) / 標準偏差
を計算し、正規化します。
3.2 フィルタリング
発現値が一定のしきい値を超える遺伝子のみを保持する場合、filter()
の中で across()
を使うことができます。
df %>%
filter(across(c(gene_A, gene_B), ~ . > 10, .names = "keep_{.col}"))
このコードは、gene_A
または gene_B
が 10 を超える行のみを抽出します。
3.3 複数の処理を同時適用
異なる処理を組み合わせることで、より柔軟なデータ処理が可能になります。
df %>%
mutate(across(c(gene_A, gene_B), list(log = log2, scale = ~ (. - mean(.)) / sd(.))))
出力:
# A tibble: 3 × 6
sample_id gene_A_log gene_A_scale gene_B_log gene_B_scale gene_C
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 S1 3.32 -1.22 2.32 -1.22 3
2 S2 3.91 0 3.32 0 6
3 S3 4.32 1.22 3.91 1.22 9
このように、log2
変換と Z スコア変換を同時に適用することも可能です。
4. まとめ
across()
を活用することで、tidyverse を使ったデータ処理がより効率的になります。特にバイオインフォマティクスのように多変量データを扱う場面では、以下のような利点があります。
✅ コードが簡潔になる:従来の mutate_at()
や summarise_at()
よりも可読性が向上。
✅ 複数の列を一括処理:データセット全体の処理が容易になる。
✅ 関数の適用を柔軟に制御:条件に応じた処理や、異なる処理の同時適用が可能。
バイオインフォマティクスにおけるデータ解析では、データの前処理やフィルタリング、正規化などが頻繁に求められます!!
across()
をうまく活用して、効率的にデータを処理していきましょう〜!