Move a column conveniently

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
9
down vote

favorite
1












There are great questions and answers on how to move a column to the first or last place.



Using dplyr The best answers are respectively analog to :



iris2 <- iris %>% head(2)
iris2 %>% select( Sepal.Width, everything()) # move Sepal.Width to first
# Sepal.Width Sepal.Length Petal.Length Petal.Width Species
# 1 3.5 5.1 1.4 0.2 setosa
# 2 3.0 4.9 1.4 0.2 setosa

iris2 %>% select(-Sepal.Width, Sepal.Width) # move Sepal.Width to last
# Sepal.Length Petal.Length Petal.Width Species Sepal.Width
# 1 5.1 1.4 0.2 setosa 3.5
# 2 4.9 1.4 0.2 setosa 3.0


However I didn't find any easy way to move a column after or before a given one.



I'm posting a rough solution below but :



  • I find it clunky

  • it doesn't leverage the flexibility of tidyverse functions to use numeric indices, names, strings etc...

I believe using vars we could also move a list of columns, or a group of column showing a pattern in the names etc... But I'm not yet so comfortable with tidyverse style programming.



So I challenge you to do better/smarter or point me to the obvious solution I've missed.



Expected output :



iris2 %>% move_at(Species, Sepal.Width, side = "before") 
# Sepal.Length Species Sepal.Width Petal.Length Petal.Width
# 1 5.1 setosa 3.5 1.4 0.2
# 2 4.9 setosa 3.0 1.4 0.2

iris2 %>% move_at(Species, Sepal.Width, side = "after")
# Sepal.Length Sepal.Width Species Petal.Length Petal.Width
# 1 5.1 3.5 setosa 1.4 0.2
# 2 4.9 3.0 setosa 1.4 0.2






share|improve this question


























    up vote
    9
    down vote

    favorite
    1












    There are great questions and answers on how to move a column to the first or last place.



    Using dplyr The best answers are respectively analog to :



    iris2 <- iris %>% head(2)
    iris2 %>% select( Sepal.Width, everything()) # move Sepal.Width to first
    # Sepal.Width Sepal.Length Petal.Length Petal.Width Species
    # 1 3.5 5.1 1.4 0.2 setosa
    # 2 3.0 4.9 1.4 0.2 setosa

    iris2 %>% select(-Sepal.Width, Sepal.Width) # move Sepal.Width to last
    # Sepal.Length Petal.Length Petal.Width Species Sepal.Width
    # 1 5.1 1.4 0.2 setosa 3.5
    # 2 4.9 1.4 0.2 setosa 3.0


    However I didn't find any easy way to move a column after or before a given one.



    I'm posting a rough solution below but :



    • I find it clunky

    • it doesn't leverage the flexibility of tidyverse functions to use numeric indices, names, strings etc...

    I believe using vars we could also move a list of columns, or a group of column showing a pattern in the names etc... But I'm not yet so comfortable with tidyverse style programming.



    So I challenge you to do better/smarter or point me to the obvious solution I've missed.



    Expected output :



    iris2 %>% move_at(Species, Sepal.Width, side = "before") 
    # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
    # 1 5.1 setosa 3.5 1.4 0.2
    # 2 4.9 setosa 3.0 1.4 0.2

    iris2 %>% move_at(Species, Sepal.Width, side = "after")
    # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
    # 1 5.1 3.5 setosa 1.4 0.2
    # 2 4.9 3.0 setosa 1.4 0.2






    share|improve this question
























      up vote
      9
      down vote

      favorite
      1









      up vote
      9
      down vote

      favorite
      1






      1





      There are great questions and answers on how to move a column to the first or last place.



      Using dplyr The best answers are respectively analog to :



      iris2 <- iris %>% head(2)
      iris2 %>% select( Sepal.Width, everything()) # move Sepal.Width to first
      # Sepal.Width Sepal.Length Petal.Length Petal.Width Species
      # 1 3.5 5.1 1.4 0.2 setosa
      # 2 3.0 4.9 1.4 0.2 setosa

      iris2 %>% select(-Sepal.Width, Sepal.Width) # move Sepal.Width to last
      # Sepal.Length Petal.Length Petal.Width Species Sepal.Width
      # 1 5.1 1.4 0.2 setosa 3.5
      # 2 4.9 1.4 0.2 setosa 3.0


      However I didn't find any easy way to move a column after or before a given one.



      I'm posting a rough solution below but :



      • I find it clunky

      • it doesn't leverage the flexibility of tidyverse functions to use numeric indices, names, strings etc...

      I believe using vars we could also move a list of columns, or a group of column showing a pattern in the names etc... But I'm not yet so comfortable with tidyverse style programming.



      So I challenge you to do better/smarter or point me to the obvious solution I've missed.



      Expected output :



      iris2 %>% move_at(Species, Sepal.Width, side = "before") 
      # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
      # 1 5.1 setosa 3.5 1.4 0.2
      # 2 4.9 setosa 3.0 1.4 0.2

      iris2 %>% move_at(Species, Sepal.Width, side = "after")
      # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
      # 1 5.1 3.5 setosa 1.4 0.2
      # 2 4.9 3.0 setosa 1.4 0.2






      share|improve this question














      There are great questions and answers on how to move a column to the first or last place.



      Using dplyr The best answers are respectively analog to :



      iris2 <- iris %>% head(2)
      iris2 %>% select( Sepal.Width, everything()) # move Sepal.Width to first
      # Sepal.Width Sepal.Length Petal.Length Petal.Width Species
      # 1 3.5 5.1 1.4 0.2 setosa
      # 2 3.0 4.9 1.4 0.2 setosa

      iris2 %>% select(-Sepal.Width, Sepal.Width) # move Sepal.Width to last
      # Sepal.Length Petal.Length Petal.Width Species Sepal.Width
      # 1 5.1 1.4 0.2 setosa 3.5
      # 2 4.9 1.4 0.2 setosa 3.0


      However I didn't find any easy way to move a column after or before a given one.



      I'm posting a rough solution below but :



      • I find it clunky

      • it doesn't leverage the flexibility of tidyverse functions to use numeric indices, names, strings etc...

      I believe using vars we could also move a list of columns, or a group of column showing a pattern in the names etc... But I'm not yet so comfortable with tidyverse style programming.



      So I challenge you to do better/smarter or point me to the obvious solution I've missed.



      Expected output :



      iris2 %>% move_at(Species, Sepal.Width, side = "before") 
      # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
      # 1 5.1 setosa 3.5 1.4 0.2
      # 2 4.9 setosa 3.0 1.4 0.2

      iris2 %>% move_at(Species, Sepal.Width, side = "after")
      # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
      # 1 5.1 3.5 setosa 1.4 0.2
      # 2 4.9 3.0 setosa 1.4 0.2








      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 30 at 16:00

























      asked Aug 30 at 12:19









      Moody_Mudskipper

      17.6k32154




      17.6k32154






















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          This seems to work, regardless of original column order (thanks for the comment to @Moody_Mudskipper ):



          iris %>% select(1:Sepal.Width, -Species, Species, everything()) %>% head(2)
          #> Sepal.Length Sepal.Width Species Petal.Length Petal.Width
          #> 1 5.1 3.5 setosa 1.4 0.2
          #> 2 4.9 3.0 setosa 1.4 0.2
          iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
          #> Sepal.Length Species Sepal.Width Petal.Length Petal.Width
          #> 1 5.1 setosa 3.5 1.4 0.2
          #> 2 4.9 setosa 3.0 1.4 0.2





          share|improve this answer






















          • I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
            – Moody_Mudskipper
            Aug 30 at 14:04






          • 1




            @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
            – Zsombor Lehoczky
            Aug 30 at 14:18











          • yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
            – Moody_Mudskipper
            Aug 30 at 14:30






          • 1




            The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            – Moody_Mudskipper
            Aug 30 at 15:35






          • 1




            Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
            – Zsombor Lehoczky
            Aug 31 at 6:50

















          up vote
          8
          down vote













          UPDATE : using rlang::enquo I could make it much better, then using @Zsombor's answer I could make it much shorter and more elegant. old solution (in base R) at the end of answer



          #' Move column or selection of columns
          #'
          #' Column(s) described by codecols are moved before (default) or after the reference column described by coderef
          #'
          #' @param data A codedata.frame
          #' @param cols unquoted column name or numeric or selection of columns using a select helper
          #' @param ref unquoted column name
          #' @param side code"before" or code"after"
          #'
          #' @return A data.frame with reordered columns
          #' @export
          #'
          #' @examples
          #' iris2 <- head(iris,2)
          #' move(iris2, Species, Sepal.Width)
          #' move(iris2, Species, Sepal.Width, "after")
          #' move(iris2, 5, 2)
          #' move(iris2, 4:5, 2)
          #' move(iris2, one_of("Sepal.Width","Species"), Sepal.Width)
          #' move(iris2, starts_with("Petal"), Sepal.Width)
          move <- function(data, cols, ref, side = c("before","after"))
          if(! requireNamespace("dplyr")) stop("Make sure package 'dplyr' is installed to use function 'move'")
          side <- match.arg(side)
          cols <- rlang::enquo(cols)
          ref <- rlang::enquo(ref)
          if(side == "before") dplyr::select(data,1:!!ref,-!!ref,-!!cols,!!cols,dplyr::everything()) else
          dplyr::select(data,1:!!ref,-!!cols,!!cols,dplyr::everything())



          examples:



          iris2 %>% move(Species, Sepal.Width)
          # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
          # 1 5.1 setosa 3.5 1.4 0.2
          # 2 4.9 setosa 3.0 1.4 0.2

          iris2 %>% move(Species, Sepal.Width, "after")
          # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
          # 1 5.1 3.5 setosa 1.4 0.2
          # 2 4.9 3.0 setosa 1.4 0.2

          iris2 %>% move(5, 2)
          # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
          # 1 5.1 setosa 3.5 1.4 0.2
          # 2 4.9 setosa 3.0 1.4 0.2

          iris2 %>% move(4:5, 2)
          # Sepal.Length Petal.Width Species Sepal.Width Petal.Length
          # 1 5.1 0.2 setosa 3.5 1.4
          # 2 4.9 0.2 setosa 3.0 1.4

          iris2 %>% move(one_of("Sepal.Width","Species"), Sepal.Width)
          # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
          # 1 5.1 3.5 setosa 1.4 0.2
          # 2 4.9 3.0 setosa 1.4 0.2

          iris2 %>% move(starts_with("Petal"), Sepal.Width)
          # Sepal.Length Petal.Length Petal.Width Sepal.Width Species
          # 1 5.1 1.4 0.2 3.5 setosa
          # 2 4.9 1.4 0.2 3.0 setosa



          Old solution referenced in question



          Here's a simple solution using only base R programming :



          move_at <- function(data, col, ref, side = c("before","after"))
          side = match.arg(side)
          col_pos <- match(as.character(substitute(col)),names(data))
          ref_pos <- match(as.character(substitute(ref)),names(data))
          sorted_pos <- c(col_pos,ref_pos)
          if(side =="after") sorted_pos <- rev(sorted_pos)
          data[c(setdiff(seq_len(ref_pos-1),col_pos),
          sorted_pos,
          setdiff(seq_along(data),c(seq_len(ref_pos),col_pos)))]


          iris2 %>% move_at(Species, Sepal.Width)
          # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
          # 1 5.1 setosa 3.5 1.4 0.2
          # 2 4.9 setosa 3.0 1.4 0.2

          iris2 %>% move_at(Species, Sepal.Width, "after")
          # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
          # 1 5.1 3.5 setosa 1.4 0.2
          # 2 4.9 3.0 setosa 1.4 0.2





          share|improve this answer






















          • Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
            – Tjebo
            Sep 3 at 22:13










          • Honoured :). What's the first if I may ask ?
            – Moody_Mudskipper
            Sep 4 at 0:08






          • 1




            of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
            – Tjebo
            Sep 4 at 6:06

















          up vote
          2
          down vote













          I found an interesting function (moveMe, written by @A5C1D2H2I1M1N2O1R2T1) that closely fits the problem:



          source('https://raw.githubusercontent.com/mrdwab/SOfun/master/R/moveMe.R')

          head(iris[ moveMe(names(iris), 'Species before Sepal.Width') ], 2)
          # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
          # 1 5.1 setosa 3.5 1.4 0.2
          # 2 4.9 setosa 3.0 1.4 0.2


          head(iris[ moveMe(names(iris), 'Species after Sepal.Width') ], 2)
          # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
          # 1 5.1 3.5 setosa 1.4 0.2
          # 2 4.9 3.0 setosa 1.4 0.2


          It also allows for more complex instructions:



          head(iris[ moveMe(names(iris), 'Species after Sepal.Width; Petal.Width first; Sepal.Length last') ], 2)
          # Petal.Width Sepal.Width Species Petal.Length Sepal.Length
          # 1 0.2 3.5 setosa 1.4 5.1
          # 2 0.2 3.0 setosa 1.4 4.9





          share|improve this answer



























            up vote
            2
            down vote













            Just for the record, another solution would be



            library(tidyverse)
            data(iris)

            iris %>%
            select(-Species) %>%
            add_column(Specis = iris$Species, .before = "Petal.Length") %>%
            head()

            #> Sepal.Length Sepal.Width Specis Petal.Length Petal.Width
            #> 1 5.1 3.5 setosa 1.4 0.2
            #> 2 4.9 3.0 setosa 1.4 0.2
            #> 3 4.7 3.2 setosa 1.3 0.2
            #> 4 4.6 3.1 setosa 1.5 0.2
            #> 5 5.0 3.6 setosa 1.4 0.2
            #> 6 5.4 3.9 setosa 1.7 0.4


            Created on 2018-08-31 by the reprex package (v0.2.0).






            share|improve this answer




















            • That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
              – Moody_Mudskipper
              Aug 31 at 7:21










            • Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
              – Daniel
              Aug 31 at 8:09










            • cool I'll take a look thanks
              – Moody_Mudskipper
              Aug 31 at 14:16










            • You have got some awesome and very useful functions in that package, Daniel!
              – Tjebo
              Sep 4 at 6:44










            • Thanks, glad you like it! :-)
              – Daniel
              Sep 4 at 9:16










            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: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            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%2f52096919%2fmove-a-column-conveniently%23new-answer', 'question_page');

            );

            Post as a guest






























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            4
            down vote



            accepted










            This seems to work, regardless of original column order (thanks for the comment to @Moody_Mudskipper ):



            iris %>% select(1:Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            #> 1 5.1 3.5 setosa 1.4 0.2
            #> 2 4.9 3.0 setosa 1.4 0.2
            iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            #> 1 5.1 setosa 3.5 1.4 0.2
            #> 2 4.9 setosa 3.0 1.4 0.2





            share|improve this answer






















            • I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
              – Moody_Mudskipper
              Aug 30 at 14:04






            • 1




              @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
              – Zsombor Lehoczky
              Aug 30 at 14:18











            • yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
              – Moody_Mudskipper
              Aug 30 at 14:30






            • 1




              The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
              – Moody_Mudskipper
              Aug 30 at 15:35






            • 1




              Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
              – Zsombor Lehoczky
              Aug 31 at 6:50














            up vote
            4
            down vote



            accepted










            This seems to work, regardless of original column order (thanks for the comment to @Moody_Mudskipper ):



            iris %>% select(1:Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            #> 1 5.1 3.5 setosa 1.4 0.2
            #> 2 4.9 3.0 setosa 1.4 0.2
            iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            #> 1 5.1 setosa 3.5 1.4 0.2
            #> 2 4.9 setosa 3.0 1.4 0.2





            share|improve this answer






















            • I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
              – Moody_Mudskipper
              Aug 30 at 14:04






            • 1




              @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
              – Zsombor Lehoczky
              Aug 30 at 14:18











            • yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
              – Moody_Mudskipper
              Aug 30 at 14:30






            • 1




              The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
              – Moody_Mudskipper
              Aug 30 at 15:35






            • 1




              Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
              – Zsombor Lehoczky
              Aug 31 at 6:50












            up vote
            4
            down vote



            accepted







            up vote
            4
            down vote



            accepted






            This seems to work, regardless of original column order (thanks for the comment to @Moody_Mudskipper ):



            iris %>% select(1:Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            #> 1 5.1 3.5 setosa 1.4 0.2
            #> 2 4.9 3.0 setosa 1.4 0.2
            iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            #> 1 5.1 setosa 3.5 1.4 0.2
            #> 2 4.9 setosa 3.0 1.4 0.2





            share|improve this answer














            This seems to work, regardless of original column order (thanks for the comment to @Moody_Mudskipper ):



            iris %>% select(1:Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            #> 1 5.1 3.5 setosa 1.4 0.2
            #> 2 4.9 3.0 setosa 1.4 0.2
            iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            #> Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            #> 1 5.1 setosa 3.5 1.4 0.2
            #> 2 4.9 setosa 3.0 1.4 0.2






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Aug 31 at 6:40

























            answered Aug 30 at 13:20









            Zsombor Lehoczky

            665




            665











            • I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
              – Moody_Mudskipper
              Aug 30 at 14:04






            • 1




              @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
              – Zsombor Lehoczky
              Aug 30 at 14:18











            • yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
              – Moody_Mudskipper
              Aug 30 at 14:30






            • 1




              The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
              – Moody_Mudskipper
              Aug 30 at 15:35






            • 1




              Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
              – Zsombor Lehoczky
              Aug 31 at 6:50
















            • I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
              – Moody_Mudskipper
              Aug 30 at 14:04






            • 1




              @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
              – Zsombor Lehoczky
              Aug 30 at 14:18











            • yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
              – Moody_Mudskipper
              Aug 30 at 14:30






            • 1




              The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
              – Moody_Mudskipper
              Aug 30 at 15:35






            • 1




              Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
              – Zsombor Lehoczky
              Aug 31 at 6:50















            I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
            – Moody_Mudskipper
            Aug 30 at 14:04




            I'm choosing this as I made it the core of my own solution, and most users don't want a new function. See my answer below for a function permitting less verbose calls.
            – Moody_Mudskipper
            Aug 30 at 14:04




            1




            1




            @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
            – Zsombor Lehoczky
            Aug 30 at 14:18





            @Moody_Mudskipper Thanks for accepting! Sure the function you wrote is much clearer to use in real code. To understand these two lines, you have to know quite a lot about tidyselect already, otherwise it's nonsense. So it's a great idea to hide the call in a function whose name describes what it is doing. I guess reordering columns isn't particularly in the focus of tidyverse, even though it's pretty important when exporting results.
            – Zsombor Lehoczky
            Aug 30 at 14:18













            yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
            – Moody_Mudskipper
            Aug 30 at 14:30




            yes, or when you want to explore the data visually as was the case that inspired this question. This discussion is relevant: github.com/tidyverse/dplyr/issues/3051#issuecomment-324646580 , @hadey says "I don't think this is such a common operation that it needs it's own verb.", speaking about moving a column to the last spot. I've seen similar issues a few times on SO though.
            – Moody_Mudskipper
            Aug 30 at 14:30




            1




            1




            The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            – Moody_Mudskipper
            Aug 30 at 15:35




            The solution needs a correction, it doesn't work if you switch Species and Sepal.width, the right solutions are iris %>% select(1:Sepal.Width,-Species, Species, everything()) %>% head(2) and iris %>% select(1:Sepal.Width, -Sepal.Width, -Species, Species, everything()) %>% head(2)
            – Moody_Mudskipper
            Aug 30 at 15:35




            1




            1




            Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
            – Zsombor Lehoczky
            Aug 31 at 6:50




            Thanks for the comment, I've edited the answer. However, this code looks even worse now. I'm pretty sure that select was not designed for this purpose, and complex column reorderings should be done using base R syntax, like your example below.
            – Zsombor Lehoczky
            Aug 31 at 6:50












            up vote
            8
            down vote













            UPDATE : using rlang::enquo I could make it much better, then using @Zsombor's answer I could make it much shorter and more elegant. old solution (in base R) at the end of answer



            #' Move column or selection of columns
            #'
            #' Column(s) described by codecols are moved before (default) or after the reference column described by coderef
            #'
            #' @param data A codedata.frame
            #' @param cols unquoted column name or numeric or selection of columns using a select helper
            #' @param ref unquoted column name
            #' @param side code"before" or code"after"
            #'
            #' @return A data.frame with reordered columns
            #' @export
            #'
            #' @examples
            #' iris2 <- head(iris,2)
            #' move(iris2, Species, Sepal.Width)
            #' move(iris2, Species, Sepal.Width, "after")
            #' move(iris2, 5, 2)
            #' move(iris2, 4:5, 2)
            #' move(iris2, one_of("Sepal.Width","Species"), Sepal.Width)
            #' move(iris2, starts_with("Petal"), Sepal.Width)
            move <- function(data, cols, ref, side = c("before","after"))
            if(! requireNamespace("dplyr")) stop("Make sure package 'dplyr' is installed to use function 'move'")
            side <- match.arg(side)
            cols <- rlang::enquo(cols)
            ref <- rlang::enquo(ref)
            if(side == "before") dplyr::select(data,1:!!ref,-!!ref,-!!cols,!!cols,dplyr::everything()) else
            dplyr::select(data,1:!!ref,-!!cols,!!cols,dplyr::everything())



            examples:



            iris2 %>% move(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(5, 2)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(4:5, 2)
            # Sepal.Length Petal.Width Species Sepal.Width Petal.Length
            # 1 5.1 0.2 setosa 3.5 1.4
            # 2 4.9 0.2 setosa 3.0 1.4

            iris2 %>% move(one_of("Sepal.Width","Species"), Sepal.Width)
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(starts_with("Petal"), Sepal.Width)
            # Sepal.Length Petal.Length Petal.Width Sepal.Width Species
            # 1 5.1 1.4 0.2 3.5 setosa
            # 2 4.9 1.4 0.2 3.0 setosa



            Old solution referenced in question



            Here's a simple solution using only base R programming :



            move_at <- function(data, col, ref, side = c("before","after"))
            side = match.arg(side)
            col_pos <- match(as.character(substitute(col)),names(data))
            ref_pos <- match(as.character(substitute(ref)),names(data))
            sorted_pos <- c(col_pos,ref_pos)
            if(side =="after") sorted_pos <- rev(sorted_pos)
            data[c(setdiff(seq_len(ref_pos-1),col_pos),
            sorted_pos,
            setdiff(seq_along(data),c(seq_len(ref_pos),col_pos)))]


            iris2 %>% move_at(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move_at(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2





            share|improve this answer






















            • Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
              – Tjebo
              Sep 3 at 22:13










            • Honoured :). What's the first if I may ask ?
              – Moody_Mudskipper
              Sep 4 at 0:08






            • 1




              of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
              – Tjebo
              Sep 4 at 6:06














            up vote
            8
            down vote













            UPDATE : using rlang::enquo I could make it much better, then using @Zsombor's answer I could make it much shorter and more elegant. old solution (in base R) at the end of answer



            #' Move column or selection of columns
            #'
            #' Column(s) described by codecols are moved before (default) or after the reference column described by coderef
            #'
            #' @param data A codedata.frame
            #' @param cols unquoted column name or numeric or selection of columns using a select helper
            #' @param ref unquoted column name
            #' @param side code"before" or code"after"
            #'
            #' @return A data.frame with reordered columns
            #' @export
            #'
            #' @examples
            #' iris2 <- head(iris,2)
            #' move(iris2, Species, Sepal.Width)
            #' move(iris2, Species, Sepal.Width, "after")
            #' move(iris2, 5, 2)
            #' move(iris2, 4:5, 2)
            #' move(iris2, one_of("Sepal.Width","Species"), Sepal.Width)
            #' move(iris2, starts_with("Petal"), Sepal.Width)
            move <- function(data, cols, ref, side = c("before","after"))
            if(! requireNamespace("dplyr")) stop("Make sure package 'dplyr' is installed to use function 'move'")
            side <- match.arg(side)
            cols <- rlang::enquo(cols)
            ref <- rlang::enquo(ref)
            if(side == "before") dplyr::select(data,1:!!ref,-!!ref,-!!cols,!!cols,dplyr::everything()) else
            dplyr::select(data,1:!!ref,-!!cols,!!cols,dplyr::everything())



            examples:



            iris2 %>% move(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(5, 2)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(4:5, 2)
            # Sepal.Length Petal.Width Species Sepal.Width Petal.Length
            # 1 5.1 0.2 setosa 3.5 1.4
            # 2 4.9 0.2 setosa 3.0 1.4

            iris2 %>% move(one_of("Sepal.Width","Species"), Sepal.Width)
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(starts_with("Petal"), Sepal.Width)
            # Sepal.Length Petal.Length Petal.Width Sepal.Width Species
            # 1 5.1 1.4 0.2 3.5 setosa
            # 2 4.9 1.4 0.2 3.0 setosa



            Old solution referenced in question



            Here's a simple solution using only base R programming :



            move_at <- function(data, col, ref, side = c("before","after"))
            side = match.arg(side)
            col_pos <- match(as.character(substitute(col)),names(data))
            ref_pos <- match(as.character(substitute(ref)),names(data))
            sorted_pos <- c(col_pos,ref_pos)
            if(side =="after") sorted_pos <- rev(sorted_pos)
            data[c(setdiff(seq_len(ref_pos-1),col_pos),
            sorted_pos,
            setdiff(seq_along(data),c(seq_len(ref_pos),col_pos)))]


            iris2 %>% move_at(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move_at(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2





            share|improve this answer






















            • Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
              – Tjebo
              Sep 3 at 22:13










            • Honoured :). What's the first if I may ask ?
              – Moody_Mudskipper
              Sep 4 at 0:08






            • 1




              of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
              – Tjebo
              Sep 4 at 6:06












            up vote
            8
            down vote










            up vote
            8
            down vote









            UPDATE : using rlang::enquo I could make it much better, then using @Zsombor's answer I could make it much shorter and more elegant. old solution (in base R) at the end of answer



            #' Move column or selection of columns
            #'
            #' Column(s) described by codecols are moved before (default) or after the reference column described by coderef
            #'
            #' @param data A codedata.frame
            #' @param cols unquoted column name or numeric or selection of columns using a select helper
            #' @param ref unquoted column name
            #' @param side code"before" or code"after"
            #'
            #' @return A data.frame with reordered columns
            #' @export
            #'
            #' @examples
            #' iris2 <- head(iris,2)
            #' move(iris2, Species, Sepal.Width)
            #' move(iris2, Species, Sepal.Width, "after")
            #' move(iris2, 5, 2)
            #' move(iris2, 4:5, 2)
            #' move(iris2, one_of("Sepal.Width","Species"), Sepal.Width)
            #' move(iris2, starts_with("Petal"), Sepal.Width)
            move <- function(data, cols, ref, side = c("before","after"))
            if(! requireNamespace("dplyr")) stop("Make sure package 'dplyr' is installed to use function 'move'")
            side <- match.arg(side)
            cols <- rlang::enquo(cols)
            ref <- rlang::enquo(ref)
            if(side == "before") dplyr::select(data,1:!!ref,-!!ref,-!!cols,!!cols,dplyr::everything()) else
            dplyr::select(data,1:!!ref,-!!cols,!!cols,dplyr::everything())



            examples:



            iris2 %>% move(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(5, 2)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(4:5, 2)
            # Sepal.Length Petal.Width Species Sepal.Width Petal.Length
            # 1 5.1 0.2 setosa 3.5 1.4
            # 2 4.9 0.2 setosa 3.0 1.4

            iris2 %>% move(one_of("Sepal.Width","Species"), Sepal.Width)
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(starts_with("Petal"), Sepal.Width)
            # Sepal.Length Petal.Length Petal.Width Sepal.Width Species
            # 1 5.1 1.4 0.2 3.5 setosa
            # 2 4.9 1.4 0.2 3.0 setosa



            Old solution referenced in question



            Here's a simple solution using only base R programming :



            move_at <- function(data, col, ref, side = c("before","after"))
            side = match.arg(side)
            col_pos <- match(as.character(substitute(col)),names(data))
            ref_pos <- match(as.character(substitute(ref)),names(data))
            sorted_pos <- c(col_pos,ref_pos)
            if(side =="after") sorted_pos <- rev(sorted_pos)
            data[c(setdiff(seq_len(ref_pos-1),col_pos),
            sorted_pos,
            setdiff(seq_along(data),c(seq_len(ref_pos),col_pos)))]


            iris2 %>% move_at(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move_at(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2





            share|improve this answer














            UPDATE : using rlang::enquo I could make it much better, then using @Zsombor's answer I could make it much shorter and more elegant. old solution (in base R) at the end of answer



            #' Move column or selection of columns
            #'
            #' Column(s) described by codecols are moved before (default) or after the reference column described by coderef
            #'
            #' @param data A codedata.frame
            #' @param cols unquoted column name or numeric or selection of columns using a select helper
            #' @param ref unquoted column name
            #' @param side code"before" or code"after"
            #'
            #' @return A data.frame with reordered columns
            #' @export
            #'
            #' @examples
            #' iris2 <- head(iris,2)
            #' move(iris2, Species, Sepal.Width)
            #' move(iris2, Species, Sepal.Width, "after")
            #' move(iris2, 5, 2)
            #' move(iris2, 4:5, 2)
            #' move(iris2, one_of("Sepal.Width","Species"), Sepal.Width)
            #' move(iris2, starts_with("Petal"), Sepal.Width)
            move <- function(data, cols, ref, side = c("before","after"))
            if(! requireNamespace("dplyr")) stop("Make sure package 'dplyr' is installed to use function 'move'")
            side <- match.arg(side)
            cols <- rlang::enquo(cols)
            ref <- rlang::enquo(ref)
            if(side == "before") dplyr::select(data,1:!!ref,-!!ref,-!!cols,!!cols,dplyr::everything()) else
            dplyr::select(data,1:!!ref,-!!cols,!!cols,dplyr::everything())



            examples:



            iris2 %>% move(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(5, 2)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move(4:5, 2)
            # Sepal.Length Petal.Width Species Sepal.Width Petal.Length
            # 1 5.1 0.2 setosa 3.5 1.4
            # 2 4.9 0.2 setosa 3.0 1.4

            iris2 %>% move(one_of("Sepal.Width","Species"), Sepal.Width)
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2

            iris2 %>% move(starts_with("Petal"), Sepal.Width)
            # Sepal.Length Petal.Length Petal.Width Sepal.Width Species
            # 1 5.1 1.4 0.2 3.5 setosa
            # 2 4.9 1.4 0.2 3.0 setosa



            Old solution referenced in question



            Here's a simple solution using only base R programming :



            move_at <- function(data, col, ref, side = c("before","after"))
            side = match.arg(side)
            col_pos <- match(as.character(substitute(col)),names(data))
            ref_pos <- match(as.character(substitute(ref)),names(data))
            sorted_pos <- c(col_pos,ref_pos)
            if(side =="after") sorted_pos <- rev(sorted_pos)
            data[c(setdiff(seq_len(ref_pos-1),col_pos),
            sorted_pos,
            setdiff(seq_along(data),c(seq_len(ref_pos),col_pos)))]


            iris2 %>% move_at(Species, Sepal.Width)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2

            iris2 %>% move_at(Species, Sepal.Width, "after")
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 3 at 8:20

























            answered Aug 30 at 12:20









            Moody_Mudskipper

            17.6k32154




            17.6k32154











            • Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
              – Tjebo
              Sep 3 at 22:13










            • Honoured :). What's the first if I may ask ?
              – Moody_Mudskipper
              Sep 4 at 0:08






            • 1




              of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
              – Tjebo
              Sep 4 at 6:06
















            • Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
              – Tjebo
              Sep 3 at 22:13










            • Honoured :). What's the first if I may ask ?
              – Moody_Mudskipper
              Sep 4 at 0:08






            • 1




              of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
              – Tjebo
              Sep 4 at 6:06















            Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
            – Tjebo
            Sep 3 at 22:13




            Awesome. That's the second @Moody_Mudskipper function which I will incorporate in my utilities :) Thanks!
            – Tjebo
            Sep 3 at 22:13












            Honoured :). What's the first if I may ask ?
            – Moody_Mudskipper
            Sep 4 at 0:08




            Honoured :). What's the first if I may ask ?
            – Moody_Mudskipper
            Sep 4 at 0:08




            1




            1




            of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
            – Tjebo
            Sep 4 at 6:06




            of course! that’s ‘get_age’ ;) stackoverflow.com/a/47529507/7941188
            – Tjebo
            Sep 4 at 6:06










            up vote
            2
            down vote













            I found an interesting function (moveMe, written by @A5C1D2H2I1M1N2O1R2T1) that closely fits the problem:



            source('https://raw.githubusercontent.com/mrdwab/SOfun/master/R/moveMe.R')

            head(iris[ moveMe(names(iris), 'Species before Sepal.Width') ], 2)
            # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
            # 1 5.1 setosa 3.5 1.4 0.2
            # 2 4.9 setosa 3.0 1.4 0.2


            head(iris[ moveMe(names(iris), 'Species after Sepal.Width') ], 2)
            # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
            # 1 5.1 3.5 setosa 1.4 0.2
            # 2 4.9 3.0 setosa 1.4 0.2


            It also allows for more complex instructions:



            head(iris[ moveMe(names(iris), 'Species after Sepal.Width; Petal.Width first; Sepal.Length last') ], 2)
            # Petal.Width Sepal.Width Species Petal.Length Sepal.Length
            # 1 0.2 3.5 setosa 1.4 5.1
            # 2 0.2 3.0 setosa 1.4 4.9





            share|improve this answer
























              up vote
              2
              down vote













              I found an interesting function (moveMe, written by @A5C1D2H2I1M1N2O1R2T1) that closely fits the problem:



              source('https://raw.githubusercontent.com/mrdwab/SOfun/master/R/moveMe.R')

              head(iris[ moveMe(names(iris), 'Species before Sepal.Width') ], 2)
              # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
              # 1 5.1 setosa 3.5 1.4 0.2
              # 2 4.9 setosa 3.0 1.4 0.2


              head(iris[ moveMe(names(iris), 'Species after Sepal.Width') ], 2)
              # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
              # 1 5.1 3.5 setosa 1.4 0.2
              # 2 4.9 3.0 setosa 1.4 0.2


              It also allows for more complex instructions:



              head(iris[ moveMe(names(iris), 'Species after Sepal.Width; Petal.Width first; Sepal.Length last') ], 2)
              # Petal.Width Sepal.Width Species Petal.Length Sepal.Length
              # 1 0.2 3.5 setosa 1.4 5.1
              # 2 0.2 3.0 setosa 1.4 4.9





              share|improve this answer






















                up vote
                2
                down vote










                up vote
                2
                down vote









                I found an interesting function (moveMe, written by @A5C1D2H2I1M1N2O1R2T1) that closely fits the problem:



                source('https://raw.githubusercontent.com/mrdwab/SOfun/master/R/moveMe.R')

                head(iris[ moveMe(names(iris), 'Species before Sepal.Width') ], 2)
                # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
                # 1 5.1 setosa 3.5 1.4 0.2
                # 2 4.9 setosa 3.0 1.4 0.2


                head(iris[ moveMe(names(iris), 'Species after Sepal.Width') ], 2)
                # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
                # 1 5.1 3.5 setosa 1.4 0.2
                # 2 4.9 3.0 setosa 1.4 0.2


                It also allows for more complex instructions:



                head(iris[ moveMe(names(iris), 'Species after Sepal.Width; Petal.Width first; Sepal.Length last') ], 2)
                # Petal.Width Sepal.Width Species Petal.Length Sepal.Length
                # 1 0.2 3.5 setosa 1.4 5.1
                # 2 0.2 3.0 setosa 1.4 4.9





                share|improve this answer












                I found an interesting function (moveMe, written by @A5C1D2H2I1M1N2O1R2T1) that closely fits the problem:



                source('https://raw.githubusercontent.com/mrdwab/SOfun/master/R/moveMe.R')

                head(iris[ moveMe(names(iris), 'Species before Sepal.Width') ], 2)
                # Sepal.Length Species Sepal.Width Petal.Length Petal.Width
                # 1 5.1 setosa 3.5 1.4 0.2
                # 2 4.9 setosa 3.0 1.4 0.2


                head(iris[ moveMe(names(iris), 'Species after Sepal.Width') ], 2)
                # Sepal.Length Sepal.Width Species Petal.Length Petal.Width
                # 1 5.1 3.5 setosa 1.4 0.2
                # 2 4.9 3.0 setosa 1.4 0.2


                It also allows for more complex instructions:



                head(iris[ moveMe(names(iris), 'Species after Sepal.Width; Petal.Width first; Sepal.Length last') ], 2)
                # Petal.Width Sepal.Width Species Petal.Length Sepal.Length
                # 1 0.2 3.5 setosa 1.4 5.1
                # 2 0.2 3.0 setosa 1.4 4.9






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Aug 30 at 13:55









                mt1022

                9,05521639




                9,05521639




















                    up vote
                    2
                    down vote













                    Just for the record, another solution would be



                    library(tidyverse)
                    data(iris)

                    iris %>%
                    select(-Species) %>%
                    add_column(Specis = iris$Species, .before = "Petal.Length") %>%
                    head()

                    #> Sepal.Length Sepal.Width Specis Petal.Length Petal.Width
                    #> 1 5.1 3.5 setosa 1.4 0.2
                    #> 2 4.9 3.0 setosa 1.4 0.2
                    #> 3 4.7 3.2 setosa 1.3 0.2
                    #> 4 4.6 3.1 setosa 1.5 0.2
                    #> 5 5.0 3.6 setosa 1.4 0.2
                    #> 6 5.4 3.9 setosa 1.7 0.4


                    Created on 2018-08-31 by the reprex package (v0.2.0).






                    share|improve this answer




















                    • That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
                      – Moody_Mudskipper
                      Aug 31 at 7:21










                    • Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
                      – Daniel
                      Aug 31 at 8:09










                    • cool I'll take a look thanks
                      – Moody_Mudskipper
                      Aug 31 at 14:16










                    • You have got some awesome and very useful functions in that package, Daniel!
                      – Tjebo
                      Sep 4 at 6:44










                    • Thanks, glad you like it! :-)
                      – Daniel
                      Sep 4 at 9:16














                    up vote
                    2
                    down vote













                    Just for the record, another solution would be



                    library(tidyverse)
                    data(iris)

                    iris %>%
                    select(-Species) %>%
                    add_column(Specis = iris$Species, .before = "Petal.Length") %>%
                    head()

                    #> Sepal.Length Sepal.Width Specis Petal.Length Petal.Width
                    #> 1 5.1 3.5 setosa 1.4 0.2
                    #> 2 4.9 3.0 setosa 1.4 0.2
                    #> 3 4.7 3.2 setosa 1.3 0.2
                    #> 4 4.6 3.1 setosa 1.5 0.2
                    #> 5 5.0 3.6 setosa 1.4 0.2
                    #> 6 5.4 3.9 setosa 1.7 0.4


                    Created on 2018-08-31 by the reprex package (v0.2.0).






                    share|improve this answer




















                    • That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
                      – Moody_Mudskipper
                      Aug 31 at 7:21










                    • Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
                      – Daniel
                      Aug 31 at 8:09










                    • cool I'll take a look thanks
                      – Moody_Mudskipper
                      Aug 31 at 14:16










                    • You have got some awesome and very useful functions in that package, Daniel!
                      – Tjebo
                      Sep 4 at 6:44










                    • Thanks, glad you like it! :-)
                      – Daniel
                      Sep 4 at 9:16












                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    Just for the record, another solution would be



                    library(tidyverse)
                    data(iris)

                    iris %>%
                    select(-Species) %>%
                    add_column(Specis = iris$Species, .before = "Petal.Length") %>%
                    head()

                    #> Sepal.Length Sepal.Width Specis Petal.Length Petal.Width
                    #> 1 5.1 3.5 setosa 1.4 0.2
                    #> 2 4.9 3.0 setosa 1.4 0.2
                    #> 3 4.7 3.2 setosa 1.3 0.2
                    #> 4 4.6 3.1 setosa 1.5 0.2
                    #> 5 5.0 3.6 setosa 1.4 0.2
                    #> 6 5.4 3.9 setosa 1.7 0.4


                    Created on 2018-08-31 by the reprex package (v0.2.0).






                    share|improve this answer












                    Just for the record, another solution would be



                    library(tidyverse)
                    data(iris)

                    iris %>%
                    select(-Species) %>%
                    add_column(Specis = iris$Species, .before = "Petal.Length") %>%
                    head()

                    #> Sepal.Length Sepal.Width Specis Petal.Length Petal.Width
                    #> 1 5.1 3.5 setosa 1.4 0.2
                    #> 2 4.9 3.0 setosa 1.4 0.2
                    #> 3 4.7 3.2 setosa 1.3 0.2
                    #> 4 4.6 3.1 setosa 1.5 0.2
                    #> 5 5.0 3.6 setosa 1.4 0.2
                    #> 6 5.4 3.9 setosa 1.7 0.4


                    Created on 2018-08-31 by the reprex package (v0.2.0).







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 31 at 7:05









                    Daniel

                    3,47441628




                    3,47441628











                    • That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
                      – Moody_Mudskipper
                      Aug 31 at 7:21










                    • Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
                      – Daniel
                      Aug 31 at 8:09










                    • cool I'll take a look thanks
                      – Moody_Mudskipper
                      Aug 31 at 14:16










                    • You have got some awesome and very useful functions in that package, Daniel!
                      – Tjebo
                      Sep 4 at 6:44










                    • Thanks, glad you like it! :-)
                      – Daniel
                      Sep 4 at 9:16
















                    • That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
                      – Moody_Mudskipper
                      Aug 31 at 7:21










                    • Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
                      – Daniel
                      Aug 31 at 8:09










                    • cool I'll take a look thanks
                      – Moody_Mudskipper
                      Aug 31 at 14:16










                    • You have got some awesome and very useful functions in that package, Daniel!
                      – Tjebo
                      Sep 4 at 6:44










                    • Thanks, glad you like it! :-)
                      – Daniel
                      Sep 4 at 9:16















                    That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
                    – Moody_Mudskipper
                    Aug 31 at 7:21




                    That's a neat solution as well, if it could leverage the stuff from ?dplyr::select_helpers and would allow "adding" existing columns I would choose it.
                    – Moody_Mudskipper
                    Aug 31 at 7:21












                    Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
                    – Daniel
                    Aug 31 at 8:09




                    Indeed, select-helpers would be nice. I have written a move_columns() function to my sjmisc package. The function is available in the current GitHub-version, and also allows select-helpers. See examples here: strengejacke.github.io/sjmisc/reference/move_columns.html
                    – Daniel
                    Aug 31 at 8:09












                    cool I'll take a look thanks
                    – Moody_Mudskipper
                    Aug 31 at 14:16




                    cool I'll take a look thanks
                    – Moody_Mudskipper
                    Aug 31 at 14:16












                    You have got some awesome and very useful functions in that package, Daniel!
                    – Tjebo
                    Sep 4 at 6:44




                    You have got some awesome and very useful functions in that package, Daniel!
                    – Tjebo
                    Sep 4 at 6:44












                    Thanks, glad you like it! :-)
                    – Daniel
                    Sep 4 at 9:16




                    Thanks, glad you like it! :-)
                    – Daniel
                    Sep 4 at 9:16

















                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52096919%2fmove-a-column-conveniently%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Comments

                    Popular posts from this blog

                    What does second last employer means? [closed]

                    List of Gilmore Girls characters

                    Confectionery