Frage

Ich habe ein kleines R-Problem mit data.table.Deine Hilfe ist sehr Willkommen.Wie mache ich das:

getResult <- function(dt, expr, gby) {
  e <- substitute(expr)
  b <- substitute(gby)
  return(dt[,eval(e),by=b])
}

v1 <- "Sepal.Length"
v2 <- "Species"

dt <- data.table(iris)
rDT <- getResult(dt, sum(v1, na.rm=TRUE), v2)

Ich erhalte folgende Fehlermeldung:

Fehler in sum(v1, na.rm = TRUE):Ungültiger 'Typ' (Zeichen) von Argument

Nun, beides v1 Und v2 von einem anderen Programm als Zeichenvariable übergeben werden, daher kann ich das nicht tun v1<- quote(Sepal.Length) was zu funktionieren scheint.

War es hilfreich?

Lösung

Eine Alternative zu Flodels Antwort in den Kommentaren könnte sein

e <- parse(text = paste0("sum(", v1, ", na.rm = TRUE)"))

b <- parse(text = v2)

rDT2 <- dt[, eval(e), by = eval(b)]

#               b    V1
# [1,]     setosa 250.3
# [2,] versicolor 296.8
# [3,]  virginica 329.4

BEARBEITEN:

Und um dies in eine Funktion zu bringen,

getResult <- function(dt, expr, gby){
  return(dt[, eval(expr), by = eval(gby)])
}

(dtR <- getResult(dt = dt, expr = e, gby = b))
# gives the same result as above


EDIT von Matthew:Es gibt einen subtilen Grund dafür paste0 Und eval \ quote Methoden können schneller sein als get in manchen Fällen auch.Einer der Gründe, warum die Gruppierung schnell erfolgen kann, ist dieser data.table inspiziert j Um zu sehen, welche Spalten verwendet werden, werden nur Teilmengen dieser verwendeten Spalten erstellt (FAQ 1.12 und 3.1).Es benutzt base::all.vars(j) das zu tun.Beim Benutzen get() In j Die verwendete Spalte ist ausgeblendet all.vars Und data.table greift für alle Fälle auf die Unterteilung aller Spalten zurück j Ausdruck braucht sie (ähnlich wie wenn der .SD Symbol wird in verwendet j, wofür .SDcols wurde zur Lösung hinzugefügt).Wenn trotzdem alle Spalten verwendet werden, macht es keinen Unterschied, aber wenn DT ist sagen wir 1e7x100 dann eine gruppierte j=sum(V1) sollte viel schneller sein als eine gruppierte j=sum(get("V1")) aus diesem Grund.Zumindest soll das passieren, und wenn nicht, liegt möglicherweise ein Fehler vor.Wenn andererseits viele Abfragen dynamisch erstellt und wiederholt werden, ist es an der Zeit, dies zu tun paste0 Und parse könnte da reinkommen.Alles hängt wirklich davon ab.Einstellung verbose=TRUE sollte eine Meldung darüber ausgeben, welche Spalten als verwendet erkannt wurden j, damit das überprüft werden kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top