How to write a function whose input is a vector and output is a character vector based on quantile...
I am writing a funcion whose input is a vector and output is a character vector of three levels: Below Avg, Avg, and Above Avg. I would like the character vector to be calucalted based on the 1st and 3rd quantiles of the vector given. When I call my function, only Below Avg returns which I understand why it returns, but do not know how to fix. Ideally I would like a new vector such that Below Avg corresponds to the values below the 1st quantile, Above Avg corresponds to values above the 3rd quantile, and Avg is everything in between.
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)
r function quantile
add a comment |
I am writing a funcion whose input is a vector and output is a character vector of three levels: Below Avg, Avg, and Above Avg. I would like the character vector to be calucalted based on the 1st and 3rd quantiles of the vector given. When I call my function, only Below Avg returns which I understand why it returns, but do not know how to fix. Ideally I would like a new vector such that Below Avg corresponds to the values below the 1st quantile, Above Avg corresponds to values above the 3rd quantile, and Avg is everything in between.
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)
r function quantile
Do you meanmapply(label_scale,x)
andsapply(x,label_scale)
? You posted those the other way around and it doesn't work at all.
– AntoniosK
Nov 21 '18 at 10:50
My apologies. That has been fixed.
– Jack Armstrong
Nov 21 '18 at 11:01
add a comment |
I am writing a funcion whose input is a vector and output is a character vector of three levels: Below Avg, Avg, and Above Avg. I would like the character vector to be calucalted based on the 1st and 3rd quantiles of the vector given. When I call my function, only Below Avg returns which I understand why it returns, but do not know how to fix. Ideally I would like a new vector such that Below Avg corresponds to the values below the 1st quantile, Above Avg corresponds to values above the 3rd quantile, and Avg is everything in between.
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)
r function quantile
I am writing a funcion whose input is a vector and output is a character vector of three levels: Below Avg, Avg, and Above Avg. I would like the character vector to be calucalted based on the 1st and 3rd quantiles of the vector given. When I call my function, only Below Avg returns which I understand why it returns, but do not know how to fix. Ideally I would like a new vector such that Below Avg corresponds to the values below the 1st quantile, Above Avg corresponds to values above the 3rd quantile, and Avg is everything in between.
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)
r function quantile
r function quantile
edited Nov 21 '18 at 11:01
Jack Armstrong
asked Nov 21 '18 at 10:43
Jack ArmstrongJack Armstrong
318519
318519
Do you meanmapply(label_scale,x)
andsapply(x,label_scale)
? You posted those the other way around and it doesn't work at all.
– AntoniosK
Nov 21 '18 at 10:50
My apologies. That has been fixed.
– Jack Armstrong
Nov 21 '18 at 11:01
add a comment |
Do you meanmapply(label_scale,x)
andsapply(x,label_scale)
? You posted those the other way around and it doesn't work at all.
– AntoniosK
Nov 21 '18 at 10:50
My apologies. That has been fixed.
– Jack Armstrong
Nov 21 '18 at 11:01
Do you mean
mapply(label_scale,x)
and sapply(x,label_scale)
? You posted those the other way around and it doesn't work at all.– AntoniosK
Nov 21 '18 at 10:50
Do you mean
mapply(label_scale,x)
and sapply(x,label_scale)
? You posted those the other way around and it doesn't work at all.– AntoniosK
Nov 21 '18 at 10:50
My apologies. That has been fixed.
– Jack Armstrong
Nov 21 '18 at 11:01
My apologies. That has been fixed.
– Jack Armstrong
Nov 21 '18 at 11:01
add a comment |
2 Answers
2
active
oldest
votes
Your problem is that you apply your function to each one of the elements of your vector and by default a given value is always equal to the quantile of that value and your process will return Below Avg
for each one of the vector elements. (Eg. x == quantile(x, 0.25)
will always return TRUE).
You should use ifelse
inside your function, which is vectorised:
# 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."
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
add a comment |
I would use cut and quantile in this situation:
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.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53410346%2fhow-to-write-a-function-whose-input-is-a-vector-and-output-is-a-character-vector%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your problem is that you apply your function to each one of the elements of your vector and by default a given value is always equal to the quantile of that value and your process will return Below Avg
for each one of the vector elements. (Eg. x == quantile(x, 0.25)
will always return TRUE).
You should use ifelse
inside your function, which is vectorised:
# 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."
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
add a comment |
Your problem is that you apply your function to each one of the elements of your vector and by default a given value is always equal to the quantile of that value and your process will return Below Avg
for each one of the vector elements. (Eg. x == quantile(x, 0.25)
will always return TRUE).
You should use ifelse
inside your function, which is vectorised:
# 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."
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
add a comment |
Your problem is that you apply your function to each one of the elements of your vector and by default a given value is always equal to the quantile of that value and your process will return Below Avg
for each one of the vector elements. (Eg. x == quantile(x, 0.25)
will always return TRUE).
You should use ifelse
inside your function, which is vectorised:
# 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."
Your problem is that you apply your function to each one of the elements of your vector and by default a given value is always equal to the quantile of that value and your process will return Below Avg
for each one of the vector elements. (Eg. x == quantile(x, 0.25)
will always return TRUE).
You should use ifelse
inside your function, which is vectorised:
# 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."
edited Nov 21 '18 at 11:00
answered Nov 21 '18 at 10:53
AntoniosKAntoniosK
12.5k1822
12.5k1822
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
add a comment |
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
This gets more complicated with more levels. The cut function is specifically designed for converting numeric vectors into character/factor vectors - see my answer.
– rookie
Nov 21 '18 at 11:14
add a comment |
I would use cut and quantile in this situation:
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.
add a comment |
I would use cut and quantile in this situation:
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.
add a comment |
I would use cut and quantile in this situation:
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.
I would use cut and quantile in this situation:
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.
edited Nov 21 '18 at 11:14
answered Nov 21 '18 at 11:00
rookierookie
763
763
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53410346%2fhow-to-write-a-function-whose-input-is-a-vector-and-output-is-a-character-vector%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do you mean
mapply(label_scale,x)
andsapply(x,label_scale)
? You posted those the other way around and it doesn't work at all.– AntoniosK
Nov 21 '18 at 10:50
My apologies. That has been fixed.
– Jack Armstrong
Nov 21 '18 at 11:01