Tidy評価:{{ }}と.data
列名を引数として安全に受け取るdplyr関数を書きます。
「Tidy評価:{{ }}と.data」はCoddyKit上の無料R Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはR Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 R Academyコースには全4レッスンが含まれています。
問題点:dplyrでのプログラミング
dplyrは非標準評価(NSE)を使用しており、列名を引用符なしで渡します。対話的な操作では便利ですが、関数を書く場合は扱いが難しくなります。列名を変数としてdplyrの関数に渡すには、どうすればよいでしょうか?
library(dplyr)
df <- data.frame(x=1:5, y=c(2,4,6,8,10))
# Works fine interactively:
df %>% summarize(mean_x = mean(x))
# But what if 'x' is a variable?
col_name <- 'x'
# df %>% summarize(result = mean(col_name)) # WRONG! treats 'col_name' as column
cat('Need tidy evaluation to solve this!'){{ }}(エンブレイス)演算子
関数内では、{{ col_var }}(「カーリーカーリー」または「エンブレイス」と呼ばれます)を使って、データフレームのコンテキストで評価される列名を渡します。これは、dplyrの関数をプログラミングする際に推奨される、一般的な方法です。
library(dplyr)
df <- data.frame(
group = c('A','A','B','B'),
sales = c(100, 120, 200, 180),
costs = c(60, 70, 110, 90)
)
# Function using {{ }}
group_mean <- function(data, group_col, value_col) {
data %>%
group_by({{ group_col }}) %>%
summarize(mean_val = mean({{ value_col }}), .groups = 'drop')
}
group_mean(df, group, sales)
group_mean(df, group, costs)出力列名に{{ }}を使う
:=の左辺で{{ }}を使うと、出力列に動的な名前を付けることもできます。:=演算子(ウォルラス演算子)を使うと、dplyrの動詞の中で、代入の左辺に変数名を指定できます。
library(dplyr)
df <- data.frame(a=1:4, b=c(2,4,6,8))
# Dynamic output column name
compute_mean <- function(data, col) {
col_name <- paste0('mean_', deparse(substitute(col)))
data %>% summarize('{col_name}' := mean({{ col }}))
}
compute_mean(df, a)
compute_mean(df, b).data代名詞
.data[['col_name']]を使うと、文字列変数で列を選択できます。これは、現在のデータフレーム内で列を検索するようdplyrに明示的に指示します。列名を文字列として持っている場合に便利です。
library(dplyr)
df <- data.frame(
name = c('Alice','Bob','Carol'),
score = c(85, 92, 78),
grade = c('B','A','C')
)
# Using .data with a string variable
get_summary <- function(data, col_name) {
data %>%
summarize(
n = n(),
mean_val = mean(.data[[col_name]])
)
}
get_summary(df, 'score')across() — 複数の列に適用する
mutate()またはsummarize()の中でacross(cols, fns)を使うと、複数の列に一度に関数を適用できます。列の選択には、starts_with()、where(is.numeric)、everything()などのtidyselectヘルパーを使用します。
library(dplyr)
df <- data.frame(
id = 1:3,
sales_q1 = c(100, 200, 150),
sales_q2 = c(120, 180, 160),
cost_q1 = c(60, 110, 80),
cost_q2 = c(70, 100, 85)
)
# Summarize all numeric columns except 'id'
df %>%
summarize(across(where(is.numeric) & !id, mean))名前付き関数でacross()を使う
across()に関数の名前付きリストを渡すと、列ごとに複数の統計量を計算できます。出力列の名前はcol_fnの形式になります。.namesを使うと、命名パターンをカスタマイズできます。
library(dplyr)
df <- data.frame(
x = c(10, 20, 30, 40),
y = c(5, 15, 25, 35)
)
# Compute mean and sd for both columns
df %>%
summarize(across(
c(x, y),
list(mean = mean, sd = sd),
.names = '{.col}_{.fn}'
))mutate()でacross()を使う
mutate()の中でacross()を使うと、複数の列を同時に変換できます。列ごとに同じ変換を繰り返し記述する必要がなくなります。
library(dplyr)
df <- data.frame(
id = 1:3,
revenue = c(1000, 2000, 1500),
cost = c(600, 1100, 800),
tax = c(100, 200, 150)
)
# Round all numeric columns except id to nearest 10
df %>%
mutate(across(where(is.numeric) & !id,
~round(., -2)))pick() — 操作用の列を選択する
pick()(dplyr 1.1以降)は、列の一部を小さなデータフレームとして選択します。データフレームを受け取る関数に渡す場合に便利です。mutate()とsummarize()の中で使用できます。
library(dplyr)
df <- data.frame(
id = 1:3,
a = c(1, 2, 3),
b = c(4, 5, 6),
c_val = c(7, 8, 9)
)
# Use pick() to compute row-wise mean across selected columns
df %>%
mutate(
row_mean = rowMeans(pick(a, b, c_val)),
row_max = do.call(pmax, pick(a, b, c_val))
)再利用可能なdplyr関数を書く
{{ }}、.data[[]]、across()を組み合わせると、強力で再利用可能な分析関数を作成できます。基本パターンは、列名を引用符なしの引数({{ }}を使用)または文字列(.data[[]]を使用)として受け取ることです。
library(dplyr)
df <- data.frame(
region = c('East','East','West','West'),
product = c('A','B','A','B'),
revenue = c(100, 200, 150, 250),
units = c(10, 15, 12, 20)
)
# Flexible grouped summary function
group_stats <- function(data, ..., metric) {
data %>%
group_by(...) %>%
summarize(
total = sum({{ metric }}),
average = mean({{ metric }}),
.groups = 'drop'
)
}
group_stats(df, region, metric = revenue)
group_stats(df, region, product, metric = units)Tidy Selectionヘルパー
Tidy Selectionヘルパーは、across()、select()、pick()の中で使用できます:starts_with()、ends_with()、contains()、matches()、num_range()、where(predicate)、everything()。
library(dplyr)
df <- data.frame(
id = 1:3,
score_2022 = c(80,85,90),
score_2023 = c(82,88,91),
score_2024 = c(85,90,93),
category = c('A','B','A')
)
# Select all score columns and compute their means
df %>%
summarize(
across(starts_with('score'), mean),
n = n()
)Tidy Evalパターンを組み合わせる
実際のdplyr関数では、グループ変数に{{ }}、複数の指標にacross()、文字列で指定された列名に.data[[]]を組み合わせることがよくあります。それぞれのパターンを使い分けることで、柔軟で正確なコードを書けるようになります。
library(dplyr)
df <- data.frame(
dept = c('HR','HR','Eng','Eng'),
salary = c(60000, 65000, 100000, 110000),
bonus = c(5000, 6000, 15000, 18000)
)
# String-based column selection with .data
summarize_column <- function(data, group_col, value_col_name) {
data %>%
group_by(.data[[group_col]]) %>%
summarize(
mean = mean(.data[[value_col_name]]),
total = sum(.data[[value_col_name]]),
.groups = 'drop'
)
}
summarize_column(df, 'dept', 'salary')
summarize_column(df, 'dept', 'bonus')理解度チェック
カスタム関数の内部で、列名を引用符なしの引数としてdplyrに渡す正しい方法は何ですか?
まとめ:Tidy Evaluation
dplyrのプログラミングにおける重要ポイント:
{{ col }}— 関数内で引用符なしの列名引数をエンブレイスします.data[['col_name']]— 文字列変数で列にアクセスします:=ウォルラス演算子 —{{ }}またはglue文字列と組み合わせて、出力名を動的に指定しますacross(cols, fns)— 複数の列に一度に関数を適用しますpick(cols)— 行単位の操作用に、列をサブデータフレームとして選択します- Tidyselectヘルパー:
starts_with()、where()、contains()、everything()
library(dplyr)
df <- data.frame(
group = c('A','A','B','B'),
v1 = c(10, 20, 30, 40),
v2 = c(5, 15, 25, 35)
)
# Reusable function using {{ }} + across
group_summary <- function(data, grp) {
data %>%
group_by({{ grp }}) %>%
summarize(across(where(is.numeric), list(mean=mean, sum=sum)), .groups='drop')
}
group_summary(df, group)AI チューターと学ぶ R — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 43
- レッスン
- 159
よくある質問
「Tidy評価:{{ }}と.data」レッスンは無料ですか?
はい。「Tidy評価:{{ }}と.data」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。
「Tidy評価:{{ }}と.data」で何を学びますか?
列名を引数として安全に受け取るdplyr関数を書きます。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
R Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Tidy評価:{{ }}と.data」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このR Academyレッスンでコードを書いて実行できますか?
はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- グループ別集計とgroup_by()
- ウィンドウ関数:lag、lead、cumsum
- dplyrでの複数テーブル結合
- Tidy評価:{{ }}と.data