少し前に、彼らはifelse
内のdplyr
の代わりにNice SQLに似た方法、つまりcase_when
を導入しました。
追加のパッケージをロードせずに、1つのdata.table
ステートメント内で異なる条件を指定できる同等の[]
はありますか?
例:
library(dplyr)
df <- data.frame(a = c("a", "b", "a"), b = c("b", "a", "a"))
df <- df %>% mutate(
new = case_when(
a == "a" & b == "b" ~ "c",
a == "b" & b == "a" ~ "d",
TRUE ~ "e")
)
a b new
1 a b c
2 b a d
3 a a e
それは確かに非常に役立ち、コードをはるかに読みやすくします(これらの場合にdplyr
を使い続ける理由の1つ)。
1)条件がデフォルトと相互に排他的で、すべての条件がfalseの場合、これは機能します。
library(data.table)
DT <- as.data.table(df) # df is from question
DT[, new := c("e", "c", "d")[1 +
1 * (a == "a" & b == "b") +
2 * (a == "b" & b == "a")]
]
与える:
> DT
a b new
1: a b c
2: b a d
3: a a e
2)条件の結果が数値の場合、さらに簡単です。たとえば、c
とd
の代わりに、デフォルトの3の10と17が必要だとします。
library(data.table)
DT <- as.data.table(df) # df is from question
DT[, new := 3 +
(10 - 3) * (a == "a" & b == "b") +
(17 - 3) * (a == "b" & b == "a")]
) 1ライナーを追加するだけでこれを実装できます。各行に少なくとも1つのTRUEレッグがあると想定しています。
when <- function(...) names(match.call()[-1])[apply(cbind(...), 1, which.max)]
# test
DT[, new := when(c = a == 'a' & b == 'b',
d = a == 'b' & b == 'a',
e = TRUE)]
これは実際の答えではありませんが、コメントとしては長すぎます。不適切と思われる場合は、投稿を削除させていただきます。
通常のtidyverse
依存関係なしに_dplyr::case_when
_を使用するオプションについて説明する RStudioコミュニティの興味深い投稿 が存在します。
要約すると、3つの選択肢が存在するようです。
dplyr
から_case_when
_を分離し、新しいパッケージをビルド lest
base
のみに依存。noplyr
、「基本的なdplyr
およびtidyr
機能を整然とした依存関係なしに提供します」。freebase
の作成者であり、「ベースRの「usethis」に似たパッケージで、「tidyverse」コードの擬似同等物です。 "、これもチェックする価値があるかもしれません。あなたが望んでいるのが_case_when
_だけの場合、lest
は_data.table
_と組み合わせると魅力的で最小限のオプションになると思います。
Tyson Barrett パッケージを最近作成 tidyfast
GitHubで利用可能(現在はバージョン_0.1.0
_として)、これは関数 "_dt_case_when
_ dplyr::case_when()
構文の場合、速度はdata.table::fifelse()
"です。
これは、@ g-grothendieckの回答のバリエーションであり、非排他的な条件で機能します。
DT[, new := c("c", "d", "e")[
apply(cbind(
a == "a" & b == "b",
a == "b" & b == "a",
TRUE), 1, which.max)]
]
DT
# a b new
# 1: a b c
# 2: b a d
# 3: a a e