Domanda

Voglio definire un metodo S4 che restituisce a Valore di ritorno scalare. Qui intendo per valore scalare, il contrario di un vettore.

setGeneric("getScalar", function(value,  ...) 
  standardGeneric("getScalar")
)
setMethod("getScalar", 
          signature(value = "ANY"),
          def = function(value, ...) getScalar(value,...), ## call external function
          valueClass = "atomic" ### atomic is false, what should I do ?
)

Non riesco a prevalere sul metodo con il suo output, voglio dire che non posso definire molte funzioni con la stessa firma con un reso diverso di restituzione: numerico, intero, carattere, .. quindi come posso farlo?

MODIFICARE Per dare più contesto:

Penso che sia atomico confuso qui. Intendo per scalare un valore numerico o un carattere booleano o un carattere, di lunghezza. Per dare più contesto avrò 3 funzioni nel mio pacchetto:

dbGetQuery   :return a list/data.frame : i.e some table rows
dbGetScalar  :return a scalar value  : i.e count(*),table_name,..
dbGetNoQuery :return nothing          : update/insert actions

È un'estensione dell'interfaccia DBI.

EDIT2

Possiamo supporre che lo scalare sia un vettore di lunghezza 1. ma non posso esprimere questa condizione usando S4. In C# o C, scrivo

double[]       // vector
double        // scalar

Forse dovrei semplicemente cambiare il nome della mia funzione.

È stato utile?

Soluzione

Una possibilità è verificare il valore del tipo di ritorno dopo la spedizione del metodo

setGeneric("getScalar", function(x, ...) {
    value <- standardGeneric("getScalar")
    if (!is.atomic(value) || length(value) != 1L)
        stop("not a scalar atomic vector")
    value
})

setMethod(getScalar, "ANY", function(x, ...) x)

Un'altra possibilità è definire una classe "scalare", con un controllo di validità sulla classe base che impone il vincolo

.Scalar <- setClass("Scalar", contains="ANY", validity=function(object) {
    if (length(object) != 1L)
        "non-scalar object"
    else TRUE
}, prototype=NA)

o controllare i tipi scalari più fortemente con una piccola gerarchia basata su una classe virtuale

setClass("Scalar", validity=function(object) {
    if (length(object) != 1L)
        "non-scalar object"
    else TRUE
})

.ScalarInteger <- setClass("ScalarInteger",
    contains=c("Scalar", "integer"),
    prototype=prototype(NA_integer_))

Questo è l'approccio adottato Bioconduttore'S Biobase pacchetto, con a mkScalar costruttore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top