为sort.data.frame创建泛型/方法一致性的最佳方法?

我终于决定把在Internet上浮动的sort.data.frame方法放到一个R包中。 它只是被请求太多而不能用于临时分配方法。

但是,它的参数写成与泛型排序函数不兼容:

sort(x,decreasing,...)
sort.data.frame(form,dat)

如果我改变sort.data.frame以减少sort.data.frame(form,decreasing,dat)和丢弃减少的参数,那么它会失去它的简单性,因为你总是必须指定dat=并且可以'真的使用位置参数。 如果我将它作为sort.data.frame(form,dat,decreasing)添加到最后,则顺序与通用函数不匹配。 如果我希望减少被陷入sort.data.frame(form,dat,...)这样的点,那么当使用基于位置的匹配时,我相信泛型函数会将第二个位置赋值为递减,并且它会得到丢弃。 协调这两个功能的最佳方式是什么?

完整的功能是:

# Sort a data frame
sort.data.frame <- function(form,dat){
# Author: Kevin Wright
# http://tolstoy.newcastle.edu.au/R/help/04/09/4300.html
# Some ideas from Andy Liaw
# http://tolstoy.newcastle.edu.au/R/help/04/07/1076.html
# Use + for ascending, - for decending.
# Sorting is left to right in the formula
# Useage is either of the following:
# sort.data.frame(~Block-Variety,Oats)
# sort.data.frame(Oats,~-Variety+Block)

# If dat is the formula, then switch form and dat
  if(inherits(dat,"formula")){
    f=dat
    dat=form
    form=f
  }
  if(form[[1]] != "~") {
    stop("Formula must be one-sided.")
  }
# Make the formula into character and remove spaces
  formc <- as.character(form[2])
  formc <- gsub(" ","",formc)
# If the first character is not + or -, add +
  if(!is.element(substring(formc,1,1),c("+","-"))) {
    formc <- paste("+",formc,sep="")
  }
# Extract the variables from the formula
  vars <- unlist(strsplit(formc, "[+-]"))
  vars <- vars[vars!=""] # Remove spurious "" terms
# Build a list of arguments to pass to "order" function
  calllist <- list()
  pos=1 # Position of + or -
  for(i in 1:length(vars)){
    varsign <- substring(formc,pos,pos)
    pos <- pos+1+nchar(vars[i])
    if(is.factor(dat[,vars[i]])){
      if(varsign=="-")
        calllist[[i]] <- -rank(dat[,vars[i]])
      else
        calllist[[i]] <- rank(dat[,vars[i]])
    }
    else {
      if(varsign=="-")
        calllist[[i]] <- -dat[,vars[i]]
      else
        calllist[[i]] <- dat[,vars[i]]
    }
  }
  dat[do.call("order",calllist),]
} 

例:

library(datasets)
sort.data.frame(~len+dose,ToothGrowth)

那里有几个问题。 sort.data.frame需要与泛型有相同的参数,所以至少需要

sort.data.frame(x, decreasing = FALSE, ...) {
....
}

要派遣工作,第一个参数需要是派发的对象。 所以我会从以下开始:

sort.data.frame(x, decreasing = FALSE, formula = ~ ., ...) {
....
}

其中x是你的datformula就是你的form ,我们提供公式的默认值来包含所有内容。 (我没有详细研究你的代码,看看究竟代表什么form 。)

当然,您不需要在通话中指定decreasing ,因此:

sort(ToothGrowth, formula = ~ len + dose)

将是如何使用上述规范调用函数。

否则,如果你不希望sort.data.frame是一个S3泛型,那么调用它其他的东西,然后你可以自由地拥有你想要的任何参数。


使用plyrarrange功能。 它允许您单独选择哪些变量应该按照升序和降序排列:

arrange(ToothGrowth, len, dose)
arrange(ToothGrowth, desc(len), dose)
arrange(ToothGrowth, len, desc(dose))
arrange(ToothGrowth, desc(len), desc(dose))

它也有一个优雅的实现:

arrange <- function (df, ...) {
  ord <- eval(substitute(order(...)), df, parent.frame())
  unrowname(df[ord, ])
}

desc只是一个普通的功能:

desc <- function (x) -xtfrm(x)

如果你正在编写这种功能,强烈建议阅读xtfrm的帮助。


你能否掩饰sort的基本定义,即类似的东西?

sort <- function(x,...) {
  if (inherits(x,"data.frame")) {
    sort.data.frame(x,...)
  } else {
    L <- list(...)
    if (!is.null(names(L))) {
      if ("decreasing" %in% names(L)) {
        decreasing <- L[["decreasing"]]
        L <- L[names(L)!="decreasing"]
      }
    } else {
      if (any(names(L)=="")) {
        dpos <- which.min(names(L)=="")
        decreasing <- L[[dpos]]
        L <- L[-dpos]
      } else decreasing <- FALSE      
    }
    arglist <- c(list(x=x,decreasing=decreasing),L)
    do.call(base::sort,arglist)
  }
}
链接地址: http://www.djcxy.com/p/12221.html

上一篇: Best way to create generic/method consistency for sort.data.frame?

下一篇: place" iterative LSD n