class - أفضل طريقة لإنشاء توافق عام/طريقة ل sort.data.frame؟




generics methods (3)

لقد قررت أخيرا لوضع الأسلوب type.data.frame الذي يطفو حول الإنترنت إلى حزمة R. ويطلب فقط أن يترك الكثير إلى طريقة مخصصة للتوزيع.

ومع ذلك، فإنه مكتوب مع الحجج التي تجعلها تتعارض مع وظيفة الفرز عام:

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

إذا قمت بتغيير sort.data.frame لاتخاذ انخفاض كوسيطة كما في sort.data.frame(form,decreasing,dat) وتجاهل التناقص، ثم يفقد بساطته لأنه سيكون لديك دائما لتحديد dat= ويمكن ' t حقا استخدام الحجج الموضعية. إذا sort.data.frame(form,dat,decreasing) إلى النهاية كما في sort.data.frame(form,dat,decreasing) ، ثم لا يتطابق الأمر مع الدالة العامة. إذا كنت آمل أن يتم القبض على انخفاض في النقاط `sort.data.frame (النموذج، دات، ...)، ثم عند استخدام مطابقة القائم على الموقف وأعتقد أن وظيفة عامة تعيين الموضع الثاني إلى خفض وسوف تحصل التخلص منها. ما هي أفضل طريقة لتنسيق هاتين الوظيفتين؟

الوظيفة الكاملة هي:

# 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)

أنا أتفق معGavin أن x يجب أن يأتي أولا. أود أن أضع المعلمة decreasing بعد formula الرغم من أنها ربما لا تستخدم كثيرا، و بالكاد من أي وقت مضى كحجة موضعية.

formula حجة formula أكثر من ذلك بكثير، وبالتالي ينبغي أن تكون الوسيطة الثانية. كما أنني أتفق بشدة معGavin أنه ينبغي أن يسمى formula ، وليس form .

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

قد ترغب في توسيع الوسيطة decreasing للسماح بناقل منطقي حيث تقابل كل قيمة ترو / فالس عمود واحد في الصيغة:

d <- data.frame(A=1:10, B=10:1)
sort(d, ~ A+B, decreasing=c(A=TRUE, B=FALSE)) # sort by decreasing A, increasing B

استخدام وظيفة arrange في plyr . انها تسمح لك لاختيار فردي المتغيرات التي ينبغي أن تكون في ترتيب تصاعدي تنازلي:

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)
  }
}




methods