Как написать функцию, чей ввод - это вектор, а вывод - это символьный вектор, основанный на квантильной информации
Я пишу функцию, чей ввод - это вектор, а вывод - символьный вектор трех уровней: ниже среднего, среднего и выше среднего. Я хотел бы, чтобы вектор символов был рассчитан на основе 1-го и 3-го квантилей данного вектора. Когда я вызываю свою функцию, только Below Avg возвращает, что я понимаю, почему она возвращается, но не знаю, как исправить. В идеале я хотел бы, чтобы новый вектор был таким, чтобы Below Avg соответствовал значениям ниже 1-го квантиля, Above Avg соответствовал значениям выше 3-го квантиля, а Avg - все, что между ними.
x<-c(1:10)
label_scale<-function(vecrr){
lq<-quantile(vecrr,0.25)
uq<-quantile(vecrr,0.75)
if(vecrr<=lq){
k<-'Below Avg.'
} else if(vecrr>=uq){
k<-'Above Avg.'
} else{
k<-'Avg.'}
return(k)
}
y<-mapply(label_scale,x)
z<-sapply(x,label_scale)
2 ответа
Ваша проблема в том, что вы применяете свою функцию к каждому из элементов вашего вектора, и по умолчанию заданное значение всегда равно квантиле этого значения, и ваш процесс вернется Below Avg
для каждого из векторных элементов. (Например. x == quantile(x, 0.25)
всегда будет возвращать TRUE).
Вы должны использовать ifelse
внутри вашей функции, которая векторизована:
# example vector
x<-c(1:10)
# function
label_scale<-function(vecrr){
lq<-quantile(vecrr,0.25)
uq<-quantile(vecrr,0.75)
ifelse(vecrr<=lq, 'Below Avg.', ifelse(vecrr>=uq, 'Above Avg.', 'Avg.'))
}
# use function on a vector
label_scale(x)
# [1] "Below Avg." "Below Avg." "Below Avg." "Avg." "Avg." "Avg." "Avg." "Above Avg."
# [9] "Above Avg." "Above Avg."
Я бы использовал cut и quantile в этой ситуации:
x <- c(1:10)
x.char <- cut(x, quantile(x, c(0,.25,.75,1)), include.lowest = T, labels = c('Below Avg.', 'Avg.','Above Avg.'))
x.char
[1] Below Avg. Below Avg. Below Avg. Avg. Avg. Avg. Avg.
[8] Above Avg. Above Avg. Above Avg.
Levels: Below Avg. Avg. Above Avg.