R - Неожиданный вывод при запуске функции в кадре данных - PullRequest
0 голосов
/ 04 июля 2018

Я пишу функцию, которая вычисляет новый столбец на основе нескольких полей в моем фрейме данных. Частью процесса является предварительная проверка диапазона одного поля ввода перед фактической обработкой. Странно то, что моя предварительная проверка всегда возвращает одно и то же значение, то есть результат предварительной проверки для первой строки кадра данных.

См. Пример ниже с упрощенной версией моей функции, которая включает только проверку. Даже если переменная должным образом передается в функцию и каждый раз отличается, результат предварительной проверки остается неизменным. Чего мне не хватает?

> my_function = function(x){
+   print(paste(x, x < 32 && x > 0))
+   if (x < 32 && x > 0) {
+     # do_something ...
+   }
+ }
> 
> df = data.frame("A" = c(10,20,30,40), "B" = c(0,10,20,30), "C" = c(40,30,20,10))
> my_function(df$A)
[1] "10 TRUE" "20 TRUE" "30 TRUE" "40 TRUE"
> my_function(df$B)
[1] "0 FALSE"  "10 FALSE" "20 FALSE" "30 FALSE"
> my_function(df$C)
[1] "40 FALSE" "30 FALSE" "20 FALSE" "10 FALSE"

1 Ответ

0 голосов
/ 04 июля 2018

Вам нужно векторизовать ifelse с одним & (вместо &&), если вы хотите проверить условие для каждого элемента вектора.

С ?ifelse

«ifelse» возвращает значение той же формы, что и «test», которое заполнены элементами, выбранными из «да» или «нет» в зависимости от о том, является ли элемент «test» «TRUE» или «FALSE».

С ?`&&`

‘&’ и ‘&&’ указывают на логическое И, а ‘|’ и ‘||’ указывают на логическое И логическое ИЛИ Более короткая форма выполняет поэлементное сравнение в во многом так же, как арифметические операторы. Длинная форма оценивает слева направо, рассматривая только первый элемент каждого вектор. Оценка продолжается только до определения результата. Более длинная форма подходит для программирования потока управления и как правило, предпочтительнее в пунктах «если».

Краткая форма & выполняет поэлементное сравнение, тогда как && оценивает только первый элемент вектора.


Вот пример, основанный на вашем df

f1 <- function(x) if (x < 32 && x > 0) x + 100 else x - 100;
f2 <- function(x) ifelse(x < 32 & x > 0, x + 100, x - 100);

f1(df$A)
#[1] 110 120 130 140

f2(df$A)
#[1] 110 120 130 -60
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...