この辺りに似たような質問がいくつかあることは知っていますが、私が抱えている正確な問題に対応しているようには見えません。
set.seed(4)
df = data.frame(
Key = c("A", "B", "A", "D", "A"),
Val1 = rnorm(5),
Val2 = runif(5),
Val3 = 1:5
)
Key == "A"である行の値列の値をゼロ化したいと思います。列名はgrep
:
cols = grep("Val", names(df), value = TRUE)
通常、この場合に必要data.table
なことを達成するには、次のようにします。
library(data.table)
df = as.data.table(df)
df[Key == "A", (cols) := 0]
そして、望ましい出力は次のようになります:
Key Val1 Val2 Val3
1 A 0.000000 0.00000000 0
2 B -1.383814 0.55925762 2
3 A 0.000000 0.00000000 0
4 D 1.437151 0.05632773 4
5 A 0.000000 0.00000000 0
ただし、今回はdplyr
、みんなが使用するチームプロジェクトに取り組んでいるため、使用する必要があります。私が提供したばかりのデータは例示であり、実際のデータは500万行を超え、16の値列が更新されます。私が思いつくことができる唯一の解決策は次のmutate_at
ように使用することです:
df %>% mutate_at(.vars = vars(cols), .funs = function(x) ifelse(df$Key == "A", 0, x))
しかし、これは私の実際のデータでは非常に遅いようです。よりエレガントで、より重要なことに、より高速なソリューションを見つけたいと思っていました。
私は使用してmap
、引用符で囲まずに!!
、使用してget
、そして:=
(これはうっとうしいこと:=
にdata.tableでマスクされる可能性があります)などを使用して多くの組み合わせを試しましたが、これらの作業がどのように有効なソリューションを構築するのに十分なほど深くないかについての私の理解はないと思います。