Cut elements from the beginning and end of an R vector












4















For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)



vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)


I did this by looping from the beginning and end, and masking out the unwanted elements.



mask <- rep(TRUE, length(vec))

# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}

# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}

cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4


This works, but I wonder if there is a more efficient way to do this, avoiding the loops.










share|improve this question























  • Maybe this: stackoverflow.com/questions/32581950/…

    – Andreas Neumeier
    Dec 30 '18 at 17:15











  • This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.

    – Ric S
    Dec 30 '18 at 17:32
















4















For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)



vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)


I did this by looping from the beginning and end, and masking out the unwanted elements.



mask <- rep(TRUE, length(vec))

# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}

# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}

cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4


This works, but I wonder if there is a more efficient way to do this, avoiding the loops.










share|improve this question























  • Maybe this: stackoverflow.com/questions/32581950/…

    – Andreas Neumeier
    Dec 30 '18 at 17:15











  • This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.

    – Ric S
    Dec 30 '18 at 17:32














4












4








4








For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)



vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)


I did this by looping from the beginning and end, and masking out the unwanted elements.



mask <- rep(TRUE, length(vec))

# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}

# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}

cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4


This works, but I wonder if there is a more efficient way to do this, avoiding the loops.










share|improve this question














For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)



vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)


I did this by looping from the beginning and end, and masking out the unwanted elements.



mask <- rep(TRUE, length(vec))

# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}

# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}

cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4


This works, but I wonder if there is a more efficient way to do this, avoiding the loops.







r






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 30 '18 at 17:13









wotuzu17wotuzu17

977




977













  • Maybe this: stackoverflow.com/questions/32581950/…

    – Andreas Neumeier
    Dec 30 '18 at 17:15











  • This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.

    – Ric S
    Dec 30 '18 at 17:32



















  • Maybe this: stackoverflow.com/questions/32581950/…

    – Andreas Neumeier
    Dec 30 '18 at 17:15











  • This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.

    – Ric S
    Dec 30 '18 at 17:32

















Maybe this: stackoverflow.com/questions/32581950/…

– Andreas Neumeier
Dec 30 '18 at 17:15





Maybe this: stackoverflow.com/questions/32581950/…

– Andreas Neumeier
Dec 30 '18 at 17:15













This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.

– Ric S
Dec 30 '18 at 17:32





This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.

– Ric S
Dec 30 '18 at 17:32












3 Answers
3






active

oldest

votes


















6














vec[ min(which(vec != 0)) : max(which(vec != 0)) ]


Basically the which(vec != 0) part gives the positions of the numbers that are different from 0, and then you take the min and max of them.






share|improve this answer



















  • 1





    good solution, but this will cause an error if vec consists only of zeros.

    – wotuzu17
    Dec 30 '18 at 18:26











  • You are right, maybe you can set an if statement to check whether that conditions occurs.

    – Ric S
    Dec 30 '18 at 19:15



















0














We could use the range and Reduce to get the sequence



vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4





share|improve this answer































    0














    Take the cumsum forward and backward of abs(vec) and keep only elements > 0. if it were known that all elements of vec were non-negative, as in the question, then we could optionally omit abs.



    vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
    ## [1] 1 2 0 3 4





    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%2f53979740%2fcut-elements-from-the-beginning-and-end-of-an-r-vector%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      6














      vec[ min(which(vec != 0)) : max(which(vec != 0)) ]


      Basically the which(vec != 0) part gives the positions of the numbers that are different from 0, and then you take the min and max of them.






      share|improve this answer



















      • 1





        good solution, but this will cause an error if vec consists only of zeros.

        – wotuzu17
        Dec 30 '18 at 18:26











      • You are right, maybe you can set an if statement to check whether that conditions occurs.

        – Ric S
        Dec 30 '18 at 19:15
















      6














      vec[ min(which(vec != 0)) : max(which(vec != 0)) ]


      Basically the which(vec != 0) part gives the positions of the numbers that are different from 0, and then you take the min and max of them.






      share|improve this answer



















      • 1





        good solution, but this will cause an error if vec consists only of zeros.

        – wotuzu17
        Dec 30 '18 at 18:26











      • You are right, maybe you can set an if statement to check whether that conditions occurs.

        – Ric S
        Dec 30 '18 at 19:15














      6












      6








      6







      vec[ min(which(vec != 0)) : max(which(vec != 0)) ]


      Basically the which(vec != 0) part gives the positions of the numbers that are different from 0, and then you take the min and max of them.






      share|improve this answer













      vec[ min(which(vec != 0)) : max(which(vec != 0)) ]


      Basically the which(vec != 0) part gives the positions of the numbers that are different from 0, and then you take the min and max of them.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Dec 30 '18 at 17:23









      Ric SRic S

      664318




      664318








      • 1





        good solution, but this will cause an error if vec consists only of zeros.

        – wotuzu17
        Dec 30 '18 at 18:26











      • You are right, maybe you can set an if statement to check whether that conditions occurs.

        – Ric S
        Dec 30 '18 at 19:15














      • 1





        good solution, but this will cause an error if vec consists only of zeros.

        – wotuzu17
        Dec 30 '18 at 18:26











      • You are right, maybe you can set an if statement to check whether that conditions occurs.

        – Ric S
        Dec 30 '18 at 19:15








      1




      1





      good solution, but this will cause an error if vec consists only of zeros.

      – wotuzu17
      Dec 30 '18 at 18:26





      good solution, but this will cause an error if vec consists only of zeros.

      – wotuzu17
      Dec 30 '18 at 18:26













      You are right, maybe you can set an if statement to check whether that conditions occurs.

      – Ric S
      Dec 30 '18 at 19:15





      You are right, maybe you can set an if statement to check whether that conditions occurs.

      – Ric S
      Dec 30 '18 at 19:15













      0














      We could use the range and Reduce to get the sequence



      vec[Reduce(`:`, range(which(vec != 0)))]
      #[1] 1 2 0 3 4





      share|improve this answer




























        0














        We could use the range and Reduce to get the sequence



        vec[Reduce(`:`, range(which(vec != 0)))]
        #[1] 1 2 0 3 4





        share|improve this answer


























          0












          0








          0







          We could use the range and Reduce to get the sequence



          vec[Reduce(`:`, range(which(vec != 0)))]
          #[1] 1 2 0 3 4





          share|improve this answer













          We could use the range and Reduce to get the sequence



          vec[Reduce(`:`, range(which(vec != 0)))]
          #[1] 1 2 0 3 4






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 30 '18 at 18:46









          akrunakrun

          405k13196269




          405k13196269























              0














              Take the cumsum forward and backward of abs(vec) and keep only elements > 0. if it were known that all elements of vec were non-negative, as in the question, then we could optionally omit abs.



              vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
              ## [1] 1 2 0 3 4





              share|improve this answer






























                0














                Take the cumsum forward and backward of abs(vec) and keep only elements > 0. if it were known that all elements of vec were non-negative, as in the question, then we could optionally omit abs.



                vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
                ## [1] 1 2 0 3 4





                share|improve this answer




























                  0












                  0








                  0







                  Take the cumsum forward and backward of abs(vec) and keep only elements > 0. if it were known that all elements of vec were non-negative, as in the question, then we could optionally omit abs.



                  vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
                  ## [1] 1 2 0 3 4





                  share|improve this answer















                  Take the cumsum forward and backward of abs(vec) and keep only elements > 0. if it were known that all elements of vec were non-negative, as in the question, then we could optionally omit abs.



                  vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
                  ## [1] 1 2 0 3 4






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Dec 30 '18 at 23:52

























                  answered Dec 30 '18 at 22:42









                  G. GrothendieckG. Grothendieck

                  147k9130235




                  147k9130235






























                      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%2f53979740%2fcut-elements-from-the-beginning-and-end-of-an-r-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

                      Monofisismo

                      Angular Downloading a file using contenturl with Basic Authentication

                      Olmecas