是否有等同于Stata;Order命令的R函数? [英] Is there an equivalent R function to Stata 'order' command?

查看:12
本文介绍了是否有等同于Stata;Order命令的R函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

R中的"ORDER"与STATA中的"SORT"类似。下面是一个数据集(仅列出变量名):

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

以下是我预期的输出:

v1 v2 v3 v4 v7 v8 v9 v10 v11 v12 v18 v13 v14 v15 v6 v16

在R中,我有两种方式:

data <- data[,c(1:5,7:12,17:18,13:15,6,16)]

names <- c("v1", "v2", "v3", "v4", "v5", "v7", "v8", "v9", "v10", "v11", "v12",  "v17", "v18", "v13", "v14", "v15", "v6", "v16")
data <- data[names]

要在Stata中获得相同的输出,我可能会运行两行:

order v17 v18, before(v13)
order v6 v16, last

在上面的理想数据中,我们可以知道要处理的变量的位置。但在大多数实际情况下,我们有像‘年龄’、‘性别’这样的变量,没有位置指标,而且一个数据集中可能有超过50个变量。那样的话,Stata中的"秩序"优势就会更加明显。我们不需要知道变量的确切位置,只需键入其名称:

order age, after(gender)

R中是否有处理此问题的基本函数,或者我可以得到一个包吗?提前谢谢。

tweetinfo <- data.frame(uid=1:50, mid=2:51, annotations=3:52, bmiddle_pic=4:53, created_at=5:54, favorited=6:55, geo=7:56, in_reply_to_screen_name=8:57, in_reply_to_status_id=9:58, in_reply_to_user_id=10:59, original_pic=11:60, reTweetId=12:61, reUserId=13:62, source=14:63, thumbnail_pic=15:64, truncated=16:65)
noretweetinfo <- data.frame(uid=21:50, mid=22:51, annotations=23:52, bmiddle_pic=24:53, created_at=25:54, favorited=26:55, geo=27:56, in_reply_to_screen_name=28:57, in_reply_to_status_id=29:58, in_reply_to_user_id=30:59, original_pic=31:60, reTweetId=32:61, reUserId=33:62, source=34:63, thumbnail_pic=35:64, truncated=36:65)
retweetinfo <- data.frame(uid=41:50, mid=42:51, annotations=43:52, bmiddle_pic=44:53, created_at=45:54, deleted=46:55, favorited=47:56, geo=48:57, in_reply_to_screen_name=49:58, in_reply_to_status_id=50:59, in_reply_to_user_id=51:60, original_pic=52:61, source=53:62, thumbnail_pic=54:63, truncated=55:64)
tweetinfo$type <- "ti"
noretweetinfo$type <- "nr"
retweetinfo$type <- "rt"
gtinfo <- rbind(tweetinfo, noretweetinfo)
gtinfo$deleted=""
gtinfo <- gtinfo[,c(1:16,18,17)]
retweetinfo <- transform(retweetinfo, reTweetId="", reUserId="")
retweetinfo <- retweetinfo[,c(1:5,7:12,17:18,13:15,6,16)]
gtinfo <- rbind(gtinfo, retweetinfo)
write.table(gtinfo, file="C:/gtinfo.txt", row.names=F, col.names=T, sep="	", quote=F)
# rm(list=ls(all=T))

推荐答案

因为我在拖延时间并尝试不同的东西,所以我创建了一个函数。最终,它取决于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
}

以下是表示数据集名称的一些示例数据:

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

现在想象一下,我们希望"v17"和"v18"在"v3"之前,"v6"和"v16"在末尾,"v5"在开头:

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"

因此,对于名为"df"的data.frame,明显的用法是:

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

并且,对于名为"dt"的data.table(正如@MNEL指出的那样,这将更有效地利用内存):

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

请注意,复合移动由分号指定。

可识别的动作包括:

  • before(将指定列移到另一个命名列之前)
  • after(将指定列移动到另一个命名列之后)
  • first(将指定的列移动到第一个位置)
  • last(将指定的列移动到最后位置)

这篇关于是否有等同于Stata;Order命令的R函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆