How to write a function whose input is a vector and output is a character vector based on quantile...












0















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)









share|improve this question

























  • 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
















0















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)









share|improve this question

























  • 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














0












0








0


0






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)









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 11:01







Jack Armstrong

















asked Nov 21 '18 at 10:43









Jack ArmstrongJack Armstrong

318519




318519













  • 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



















  • 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

















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












2 Answers
2






active

oldest

votes


















1














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."





share|improve this answer


























  • 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



















0














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.





share|improve this answer

























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    1














    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."





    share|improve this answer


























    • 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
















    1














    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."





    share|improve this answer


























    • 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














    1












    1








    1







    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."





    share|improve this answer















    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."






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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



















    • 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













    0














    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.





    share|improve this answer






























      0














      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.





      share|improve this answer




























        0












        0








        0







        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.





        share|improve this answer















        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.






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 '18 at 11:14

























        answered Nov 21 '18 at 11:00









        rookierookie

        763




        763






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin