Các giải pháp này (1) duy trì đường ống, (2) không ghi đè đầu vào và (3) chỉ yêu cầu điều kiện được chỉ định một lần:
1a) mutate_cond Tạo một hàm đơn giản cho khung dữ liệu hoặc bảng dữ liệu có thể được kết hợp vào đường ống. Hàm này giống như mutate
nhưng chỉ hoạt động trên các hàng thỏa mãn điều kiện:
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 Đây là một hàm thay thế cho các khung dữ liệu hoặc bảng dữ liệu giống như vậy mutate
nhưng chỉ được sử dụng trong group_by
(như trong ví dụ bên dưới) và chỉ hoạt động trên nhóm cuối cùng thay vì mọi nhóm. Lưu ý rằng TRUE> FALSE nên nếu group_by
chỉ định một điều kiện thì mutate_last
sẽ chỉ hoạt động trên các hàng thỏa mãn điều kiện đó.
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) điều kiện ra yếu tố loại bỏ điều kiện bằng cách biến nó thành một cột bổ sung mà sau này sẽ bị loại bỏ. Sau đó, sử dụng ifelse
, replace
hoặc số học với logic như minh họa. Điều này cũng hoạt động cho các bảng dữ liệu.
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) sqldf Chúng tôi có thể sử dụng SQL update
thông qua gói sqldf trong đường dẫn cho khung dữ liệu (nhưng không phải bảng dữ liệu trừ khi chúng tôi chuyển đổi chúng - điều này có thể đại diện cho một lỗi trong dplyr. Xem dplyr issue 1579 ). Có vẻ như chúng tôi đang sửa đổi đầu vào trong mã này một cách không thể tránh khỏi do sự tồn tại của update
nhưng trên thực tế, update
nó đang hoạt động trên bản sao của đầu vào trong cơ sở dữ liệu được tạo tạm thời chứ không phải trên đầu vào thực tế.
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 Cũng kiểm tra row_case_when
được xác định trong
Trả lại một tibble: làm thế nào để vectơ hóa với case_when? . Nó sử dụng một cú pháp tương tự như case_when
nhưng áp dụng cho các hàng.
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)
)
Lưu ý 1: Chúng tôi sử dụng điều này như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))
Lưu ý 2: Vấn đề làm thế nào để dễ dàng chỉ định cập nhật một tập hợp con của các hàng cũng được thảo luận trong các vấn đề dplyr 134 , 631 , 1518 và 1573 với 631 là chủ đề chính và 1573 là đánh giá các câu trả lời ở đây.