2017-02-05 5 views
1

Я пытаюсь добавить mutate новую переменную условно на значение другой переменной с использованием if_else, но if_else настаивает на вычислении всех значений, а затем условной замене значений в конечном векторе.dplyr: if_else is greedy

Такое поведение является проблематичным, когда функция, которая приводит к конечным значениям для некоторых случаев не может быть вычислена для других случаев:

df_foo = data_frame(
    rate = sample(c(0, 0.1), size = 100, replace = TRUE), 
    pmt = 1000, 
    nper = 10 
) 

df_foo %>% 
    mutate(
    if_else(
     rate > 0, 
     optiRum::PV(rate = rate, pmt = -pmt, nper = nper), 
     0 
    ) 
) 

Есть ли способ, чтобы только вычислить TRUE значения, когда условие TRUE?

+0

что-то вроде 'df_foo%>% group_by (хх = скорости> 0)%>% мутировать (if_else (хх, SQRT (ФЭУ), 0)) 'должен помочь вам. замените своей функцией –

+0

@ joel.wilson Спасибо. Должен признаться, я был немного удивлен этим поведением. Не уверен, что я не должен быть. Я думаю, что он побеждает цель 'if_else' при вычислении обоих векторов для всех случаев. Во всяком случае, ваше решение должно работать в форме, поэтому спасибо за это. – tchakravarty

+0

на самом деле даже 'df_foo%>% mutate (if_else (rate> 0, sqrt (pmt), 0))' работает честно !! Я не уверен в функции, которую вы используете. перепроверить функцию 'PV' на самом деле –

ответ

0

Это не является проблемой для if_else, базовая версия ifelse действует одинаково. С помощью файла ifelse мы можем прочитать:

Если yes или no слишком коротки, их элементы перерабатываются. yes будет оценен тогда и только тогда, когда любой элемент test является истинным, и аналогичным образом для no.

Существует множество случаев, когда использование ifelse неприемлемо, а предупреждение об ошибках в одном из условий - одно.

Решение делать то, что вы хотите (без dplyr) является:

df_foo$x <- 0 
df_foo$x[df_foo$rate > 0] <- with(df_foo[df_foo$rate > 0, ], optiRum::PV(rate, nper, -pmt))