Страница 1 из 1
Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 16 июл 2020, 19:48
VistaSV30
Добрый день!
У меня есть функция для вычисления прироста:
Код: Выделить всё
tr <- function(d1, d2){
if (d1>0) s = round((d2 - d1) / d1 * 100, 1)
if (s > 99.999) s = paste('\u2b\u432', round(d2 / d1, 1), '\u440\u430\u437\u430')
return(s)
}
Отдельные значения функция вычисляет корректно, но с векторами такого не получается. Например,
> tr(2,7)
[1] "+в 3.5 раза"
А если использовать векторы в качестве аргументов, то не получается:
Код: Выделить всё
n1 <- sample(0:5, 10, replace = T)
n2 <- sample(0:5, 10, replace = T)
> n1
[1] 3 5 4 1 3 1 0 0 2 5
> n2
[1] 5 4 2 3 3 5 2 1 2 2
> tr(n1,n2)
[1] 66.7 -20.0 -50.0 200.0 0.0 400.0 Inf Inf 0.0 -60.0
Предупреждения:
1: В if (d1 > 0) s = round((d2 - d1)/d1 * 100, 1) :
длина условия > 1, будет использован только первый элемент
2: В if (s > 99.999) s = paste("+в", round(d2/d1, 1), "раза") :
длина условия > 1, будет использован только первый элемент
Может быть как-то по другому надо задавать условия?
Подскажите пожалуйста!
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 16 июл 2020, 20:44
gamm
Там же зеленым по русски написано, что нельзя в условие вектор вставлять. Либо цикл, что медленно, либо векторизация: вычислить логический индекс (маску искомых элементов), и использовать ее для изменения. Уже проходили на одном из предыдущих занятий

Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 09:02
VistaSV30
Вот так теперь работает как надо:
Код: Выделить всё
# Прирост
tr <- function(d1, d2, Percent = NULL ){
s = round((d2 - d1) / d1 * 100, 1)
s1 <- s
s2 <- paste('\u2b\u432', sprintf("%1.1f", d2 / d1), '\u440\u430\u437\u430')
s1[s == 0] <- '\u443\u440\u43e\u432\u2e'
s1[s == -100] <- "-"
s1[s >= 100] <- s2[s >= 100]
s1[is.infinite(s) == TRUE] <- "+"
return(s1)
}
Сейчас еще придумаю как знак % добавлять
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 09:15
gamm
VistaSV30 писал(а): ↑17 июл 2020, 09:02
То есть, сначала нужно создать вектор из результатов вычислений, а потом функцией which() искать значения по условиям?
нет, вас все время на последовательную обработку тянет. Нужно векторизовать. Уже делали, примерно так
Код: Выделить всё
s<-rep("-",length(d1))
s[d1 == d2] = "уровень"
s[d1 == 0 && d2 == 0] = "-"
s[d1 == 0 && d2 > ] = "+"
s[d1 > 0 && d2 == 0] = "-"
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 09:54
VistaSV30
Ой!
Пока исправлял свой вопрос мне уже ответили.
По-моему, теперь сделал как надо. (Если Percent != NULL, то к результату добавляется знак %)
Код: Выделить всё
# Прирост
tr <- function(d1, d2, Percent = NULL ){
s = round((d2 - d1) / d1 * 100, 1)
s1 <- s
s2 <- paste('\u2b\u432', sprintf("%1.1f", d2 / d1), '\u440\u430\u437\u430')
s1[s == -100] <- "-"
d1[d1 == 0] <- 1e-10
s1[(d2/d1)>=2] <- s2[(d2/d1)>=2]
s1[is.infinite(s) == TRUE] <- "+"
s1[is.na(s) == TRUE] <- "-"
s2 <- paste0(s,"%")
s1[abs(s) < 100 & is.null(Percent) == FALSE] <- s2[abs(s) < 100]
s1[s == 0] <- '\u443\u440\u43e\u432\u2e'
return(s1)
}
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 10:24
nickleb
Код: Выделить всё
TR <- sapply(seq_along(n1),
function (i) {tr(n1[i], n2[i])})
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 10:42
nickleb
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 11:02
nickleb
VistaSV30 писал(а): ↑16 июл 2020, 19:48
Отдельные значения
... а "отдельные значения" - в Вашем контексте - так это скаляры, которые по R-сути являются векторами длинной единица
Re: Пользовательская функция по разному обрабатывает значения и векторы
Добавлено: 17 июл 2020, 11:03
VistaSV30
Решил все-таки использовать свой вариант функции, сделанный по советам gamm.
Поскольку в итоге планирую все функции собрать в один пакет.
Спасибо еще раз!