#r #dplyr
#r #dplyr
Вопрос:
library(tidyverse)
set.seed(041019)
Я определил простую функцию, которая добавляет 2 столбца вместе, например, в этом примере:
# data
dat <- data.frame("x" = sample(1:100, 10), "y" = sample(1:100, 10))
# define function
addXY <- function(dat) {
datOut <- dat %>%
mutate(z = x y)
return(datOut)
}
addXY(dat)
x y z
1 80 30 110
2 28 16 44
3 11 61 72
4 37 24 61
5 29 44 73
6 62 33 95
7 94 50 144
8 59 59 118
9 88 39 127
10 65 78 143
Допустим, я хочу добавить двоичный аргумент к этой функции и использовать его для условной фильтрации в цепочке dplyr. Как бы я правильно это сделал. Я пробовал это, но это не работает:
addXY <- function(dat, aboveFifty = TRUE) {
datOut -> dat %>%
if (!aboveFifty) {filter(x < 50)} else {filter(x <= 100)} %>%
mutate(z = x y)
return(datOut)
}
addXY(dat, aboveFifty = FALSE)
Сбой с сообщением об ошибке:
Error in if (.) !aboveFifty else { :
argument is not interpretable as logical
In addition: Warning message:
In if (.) !aboveFifty else { :
the condition has length > 1 and only the first element will be used
Похоже, что он пытается фильтровать аргумент, а не данные, что, очевидно, не то, что я хочу.
Комментарии:
1. Опечатка, отредактировано сейчас.
2. В настоящее время неясно, куда / что
dat
передается по каналу. Вы можете обойти это, заключив весь оператор в фигурные скобки и используя точкиfilter()
. Нравитсяdat %>% {if (!aboveFifty) {filter(., x < 50)} else {filter(., x <= 100)} }
3. хороший. Это работает. Спасибо
4. Поскольку у вас уже есть эта операция фильтрации в функции, вы можете добавить присвоение пороговой переменной, а затем выполнить фильтрацию на основе этого
Ответ №1:
Вы можете поместить if
оператор в свой filter
:
addXY <- function(x, aboveFifty = T) x %>%
filter(if (aboveFifty) x < 50 else x < 100) %>%
mutate(z = x y)
addXY(dat)
x y z
1 28 16 44
2 11 61 72
3 37 24 61
4 29 44 73