Интерпретация “имеет длину> 1” предупреждение от функции `if`
У меня есть массив:
a <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
и хотел бы реализовать следующую функцию:
w0){ a/sum(a) } else 1 }
Эта функция хотела бы проверить, существует ли какое-либо значение больше, чем 0, и если да, то разделите каждый элемент на сумму суммы.
- data.frame без разрушения имен столбцов
- Формат чисел до значительных цифр в R
- Ошибка: использование стека C слишком близко к пределу
- Создание системы Prompt / Answer для ввода данных в R
- Использование gsub для извлечения символьной строки перед пробелом в R
В противном случае он должен просто записать 1.
Появляется следующее предупреждающее сообщение:
Warning message: In if (a > 0) { : the condition has length > 1 and only the first element will be used
Как я могу исправить функцию?
- Возвращаемый индекс наименьшего значения в векторе?
- Перемещение столбцов в data.frame () без повторного набора
- добавление NA, чтобы все элементы списка равны длине
- Преобразование серийного номера excel DateTime в R DateTime
- Разделите аргументы `...` и распределите по нескольким функциям
- R: преобразовать строку с разделителями в переменные
- R: t-тест по всем столбцам
- Отменить список фреймов данных
возможно, вы хотите ifelse
:
a <- c(1,1,1,1,0,0,0,0,2,2) ifelse(a>0,a/sum(a),1) [1] 0.125 0.125 0.125 0.125 1.000 1.000 1.000 1.000 [9] 0.250 0.250
if
оператор не векторизован. Для векторизованных операторов if вы должны использовать ifelse
. В вашем случае достаточно написать
w <- function(a){ if (any(a>0)){ a/sum(a) } else 1 }
или короткой векторной версии
ifelse(a > 0, a/sum(a), 1)
Это зависит от того, что вы хотите использовать, потому что первая функция дает выходной вектор длины 1 (в другой части), а ifelse
дает выходной вектор длины, равный длине a
.
Вот простой способ без ifelse
:
(a/sum(a))^(a>0)
Пример:
a <- c(0, 1, 0, 0, 1, 1, 0, 1) (a/sum(a))^(a>0) [1] 1.00 0.25 1.00 1.00 0.25 0.25 1.00 0.25
Просто добавив точку в целом дискуссию о том, почему это предупреждение появляется (мне было непонятно раньше). Причина, по которой это делается, как упоминалось ранее, заключается в том, что «a» в этом случае является вектором, а неравенство «a> 0» создает другой вектор TRUE и FALSE (где «a» -> 0 или нет).
Если вы хотите вместо этого проверить, имеет ли значение «a> 0», вы можете использовать функции «any» или «all»,
Лучший
То, как я рассматриваю этот вопрос, было, когда я пытался сделать что-то подобное, когда я определял функцию, и ее вызывали с массивом, как и другие, указывали
Вы могли бы сделать что-то подобное, но для этих сценариев это менее элегантно по сравнению с методом Свена.
sapply(a, function(x) afunc(x)) afunc<-function(a){ if (a>0){ a/sum(a) } else 1 }