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











up vote
0
down vote

favorite












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
    2 days ago










  • My apologies. That has been fixed.
    – Jack Armstrong
    2 days ago















up vote
0
down vote

favorite












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
    2 days ago










  • My apologies. That has been fixed.
    – Jack Armstrong
    2 days ago













up vote
0
down vote

favorite









up vote
0
down vote

favorite











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 2 days ago

























asked 2 days ago









Jack Armstrong

288519




288519












  • 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
    2 days ago










  • My apologies. That has been fixed.
    – Jack Armstrong
    2 days ago


















  • 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
    2 days ago










  • My apologies. That has been fixed.
    – Jack Armstrong
    2 days ago
















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
2 days ago




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
2 days ago












My apologies. That has been fixed.
– Jack Armstrong
2 days ago




My apologies. That has been fixed.
– Jack Armstrong
2 days ago












2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










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
    2 days ago


















up vote
0
down vote













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',
    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








    up vote
    1
    down vote



    accepted










    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
      2 days ago















    up vote
    1
    down vote



    accepted










    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
      2 days ago













    up vote
    1
    down vote



    accepted







    up vote
    1
    down vote



    accepted






    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 2 days ago

























    answered 2 days ago









    AntoniosK

    12.1k1822




    12.1k1822












    • 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
      2 days ago


















    • 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
      2 days ago
















    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
    2 days ago




    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
    2 days ago












    up vote
    0
    down vote













    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



























      up vote
      0
      down vote













      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

























        up vote
        0
        down vote










        up vote
        0
        down vote









        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 2 days ago

























        answered 2 days ago









        rookie

        663




        663






























             

            draft saved


            draft discarded



















































             


            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

            Contact image not getting when fetch all contact list from iPhone by CNContact

            count number of partitions of a set with n elements into k subsets

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks