これらのソリューションは、(1)パイプラインを維持し、(2)入力を上書きせず、(3)条件を1回指定するだけで済みます。
1a)mutate_condパイプラインに組み込むことができるデータフレームまたはデータテーブルの単純な関数を作成します。この関数は似てmutate
いますが、条件を満たす行にのみ作用します。
mutate_cond <- function(.data, condition, ..., envir = parent.frame()) {
condition <- eval(substitute(condition), .data, envir)
.data[condition, ] <- .data[condition, ] %>% mutate(...)
.data
}
DF %>% mutate_cond(measure == 'exit', qty.exit = qty, cf = 0, delta.watts = 13)
1b)mutate_lastこれは、データフレームまたはデータテーブルの代替関数です。これも同様ですmutate
が、group_by
(以下の例のように)内部でのみ使用され、すべてのグループではなく最後のグループでのみ動作します。TRUE> FALSEであるためgroup_by
、条件を指定すると、mutate_last
その条件を満たす行でのみ動作することに注意してください。
mutate_last <- function(.data, ...) {
n <- n_groups(.data)
indices <- attr(.data, "indices")[[n]] + 1
.data[indices, ] <- .data[indices, ] %>% mutate(...)
.data
}
DF %>%
group_by(is.exit = measure == 'exit') %>%
mutate_last(qty.exit = qty, cf = 0, delta.watts = 13) %>%
ungroup() %>%
select(-is.exit)
2)条件を除外する後で削除される余分な列にすることで、条件を除外します。その後、使用ifelse
、replace
示されるように論理名または算術。これはデータテーブルでも機能します。
library(dplyr)
DF %>% mutate(is.exit = measure == 'exit',
qty.exit = ifelse(is.exit, qty, qty.exit),
cf = (!is.exit) * cf,
delta.watts = replace(delta.watts, is.exit, 13)) %>%
select(-is.exit)
3)sqldfupdate
データフレームのパイプラインでsqldfパッケージを介してSQLを使用できます(ただし、変換しない限りデータテーブルは使用できません。これはdplyrのバグを表している可能性があります。dplyrの問題1579を参照してください)。我々が望ましくない原因の存在にこのコードで入力を変更していることに思えるかもしれませんupdate
が、実際にはupdate
、一時的に生成されたデータベース内の入力のコピーではなく実際の入力に作用しています。
library(sqldf)
DF %>%
do(sqldf(c("update '.'
set 'qty.exit' = qty, cf = 0, 'delta.watts' = 13
where measure = 'exit'",
"select * from '.'")))
4)row_case_when「チブルrow_case_when
を返す:case_whenでベクトル化する方法」で定義され
ているものも確認してください。。これは、case_when
行に似ていますが適用される構文を使用します。
library(dplyr)
DF %>%
row_case_when(
measure == "exit" ~ data.frame(qty.exit = qty, cf = 0, delta.watts = 13),
TRUE ~ data.frame(qty.exit, cf, delta.watts)
)
注1:これをDF
set.seed(1)
DF <- data.frame(site = sample(1:6, 50, replace=T),
space = sample(1:4, 50, replace=T),
measure = sample(c('cfl', 'led', 'linear', 'exit'), 50,
replace=T),
qty = round(runif(50) * 30),
qty.exit = 0,
delta.watts = sample(10.5:100.5, 50, replace=T),
cf = runif(50))
注2:簡単に行のサブセットを更新指定する方法の問題もdplyrの問題が議論されている134、631、1518年と1573年をと631は、メインスレッドであることと、1573年はここに答えの見直しいます。