이러한 솔루션은 (1) 파이프 라인을 유지하고, (2) 입력을 덮어 쓰지 않으며 , (3) 조건을 한 번만 지정하면됩니다.
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 또한 티블 반환 : case_when으로 벡터화하는 방법에row_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 이 여기에 대한 답변 검토입니다.