Когда у вас есть более сложная логика, подобная этой, я считаю, что обычно лучше обернуть ее в функцию. В будущем будет легче поддерживать, читать и отлаживать. Я также был бы очень осторожен при использовании большого количества вложенных ifelse-операторов или больших case_when. В принятом ответе q
может быть только 2, 3 или 4. Не предусмотрено ни одного случая, чтобы q
было равно 1, что вам, безусловно, нужно в качестве опции в вашем конечном продукте.
df <- tibble::tribble(
~val, ~q0, ~q1, ~q2, ~q3, ~q4, ~q, ~diff,
15L, 15L, 15L, 15L, 15, 15L, 4L, 0,
17L, 2L, 16L, 30L, 34, 54L, 2L, 13,
29L, 2L, 16L, 30L, 34, 54L, 2L, 1,
25L, 2L, 17L, 20L, 26, 43L, 3L, 1 )
whichQ <- function(df, qs = c('q0', 'q1', 'q2', 'q3', 'q4')) {
# This has the flexibility of changing your column names / using more or less Q splits
qDf <- df[, qs]
# This finds the right quantile by finding how many you are larger than
# It works because the q's are sequential
whichGreater <- df$val >= qDf
q <- apply(whichGreater, 1, sum)
# 4 is a special case because there is no next quantile
q <- ifelse(q == 5, 4, q)
df$q <- q
# Go through the Qs we found and grab the value of that column
diff <- sapply(seq_along(q), function(x) {
as.integer(qDf[x, q[x]+1])
})
# Get the difference
df$diff <- diff - df$val
df
}
Вы все еще можете использовать это с трубопроводом, но это более ясно (я думаю), что происходит, если вы называете свою функцию чем-то полезным.
df %>%
whichQ %>%
head(2)