Is there an equivalent R function to Stata 'order' command?

后端 未结 6 1222
旧时难觅i
旧时难觅i 2021-01-13 11:09

\'order\' in R seems like \'sort\' in Stata. Here\'s a dataset for example (only variable names listed):

v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v

6条回答
  •  执念已碎
    2021-01-13 11:50

    Because I'm procrastinating and experimenting with different things, here's a function that I whipped up. Ultimately, it depends on append:

    moveme <- function(invec, movecommand) {
      movecommand <- lapply(strsplit(strsplit(movecommand, ";")[[1]], ",|\\s+"), 
                            function(x) x[x != ""])
      movelist <- lapply(movecommand, function(x) {
        Where <- x[which(x %in% c("before", "after", "first", "last")):length(x)]
        ToMove <- setdiff(x, Where)
        list(ToMove, Where)
      })
      myVec <- invec
      for (i in seq_along(movelist)) {
        temp <- setdiff(myVec, movelist[[i]][[1]])
        A <- movelist[[i]][[2]][1]
        if (A %in% c("before", "after")) {
          ba <- movelist[[i]][[2]][2]
          if (A == "before") {
            after <- match(ba, temp)-1
          } else if (A == "after") {
            after <- match(ba, temp)
          }    
        } else if (A == "first") {
          after <- 0
        } else if (A == "last") {
          after <- length(myVec)
        }
        myVec <- append(temp, values = movelist[[i]][[1]], after = after)
      }
      myVec
    }
    

    Here's some sample data representing the names of your dataset:

    x <- paste0("v", 1:18)
    

    Imagine now that we wanted "v17" and "v18" before "v3", "v6" and "v16" at the end, and "v5" at the beginning:

    moveme(x, "v17, v18 before v3; v6, v16 last; v5 first")
    #  [1] "v5"  "v1"  "v2"  "v17" "v18" "v3"  "v4"  "v7"  "v8"  "v9"  "v10" "v11" "v12"
    # [14] "v13" "v14" "v15" "v6"  "v16"
    

    So, the obvious usage would be, for a data.frame named "df":

    df[moveme(names(df), "how you want to move the columns")]
    

    And, for a data.table named "DT" (which, as @mnel points out, would be more memory efficient):

    setcolorder(DT, moveme(names(DT), "how you want to move the columns"))
    

    Note that compound moves are specified by semicolons.

    The recognized moves are:

    • before (move the specified columns to before another named column)
    • after (move the specified columns to after another named column)
    • first (move the specified columns to the first position)
    • last (move the specified columns to the last position)

提交回复
热议问题