Woher weiß ich, dass eine Funktion oder eine Operation in R vektorisiert ist?

8

Ich lerne noch R. Gibt es eine automatisierte Methode, um festzustellen, ob ein R operationoder ein functionist vectorized? Um zu identifizieren, ob ein RObjekt ein ist vector, kann ich verwenden is.vector(x), das zurückgibt, TRUEob xes sich um einen Vektor handelt oder Falsenicht. Gibt es etwas ähnliches für vectorized?

Zum Beispiel:

x <- c(1,2,3)
y <- c(3,4,5)
x+y
#[1] 4 6 8

Da +es vektorisiert wird, werden automatisch addseinzelne Elemente eines Vektors xmit einzelnen Elementen von y. Andernfalls müsste ich eine forSchleife verwenden, um eine ähnliche Ausgabe zu erzielen.

for(i in seq_along(x)){
  cat(sprintf("%i ", x[i]+y[i]))
}
#4 6 8 

Mein bisher begrenztes Verständnis des Begriffs Vectorizedbeinhaltet die automatische Bearbeitung von Elementen, die ich sonst einzeln für einzelne Elemente eines Vektors ausführen müsste.

Gibt es eine Methode, die Sie empfehlen, um festzustellen, ob ein operationoder ein functionIn vorhanden Rist vectorized?

Vielen Dank.

Anon Mousy
quelle

Antworten:

3

Vektorisierung in R bedeutet im Grunde, dass jede Schleife in eine schnellere, kompilierte Sprache wie C oder FORTRAN verschoben wird. Damit dies geschieht, sollten die fraglichen Vektoren "atomar" sein - dh "flach" und homogen - und der Vektortyp, mit dem Sie überprüfen können typeof(), sollte für die ausgeführten Operationen sinnvoll sein. Wenn es atomar ist, wird es vektorisiert.

Sie können mit überprüfen, ob ein Vektor atomar ist is.atomic(). Ein anderer Vektortyp, der nicht vektorisiert ist, heißt "rekursiv" und kann mit überprüft werden is.recursive(). Rekursive Objekte können andere Objekte eines beliebigen Typs enthalten, dh sie können heterogen sein. Listen und Datenrahmen sind rekursiv.

Versuchen Sie etwas wie das Folgende, um einen Einblick in Atomic vs. Recursive zu erhalten:

# Atomic:
1
1:3
c("a", "b", "c")
c(T, F, T)

# Recursive:
list(nums = 1:3, letts = c("a", "b", "c"), logics = c(T, F, T))
data.frame(nums = 1:3, letts = c("a", "b", "c"), logics = c(T, F, T))

# Vectors can be atomic or recursive:
is.vector(1:9) # TRUE
is.atomic(1:9) # TRUE
is.recursive(1:9) # FALSE

is.vector(list(nums = 1:9, chars = "x")) # TRUE
is.atomic(list(1:9)) # FALSE
is.recursive(list(1:9)) # TRUE

# Matrices are atomic, data frames are recursive:
is.vector(matrix(1:9, 3)) # FALSE
is.atomic(matrix(1:9, 3)) # TRUE
is.recursive(matrix(1:9, 3)) # FALSE

is.vector(as.data.frame(matrix(1:9, 3))) # FALSE
is.atomic(as.data.frame(matrix(1:9, 3))) # FALSE
is.recursive(as.data.frame(matrix(1:9, 3))) # TRUE

Ich denke, Sie können davon ausgehen, dass viele, wenn nicht die meisten der von Ihnen am häufigsten verwendeten R-Funktionen vektorisiert sind. Ich glaube nicht, dass es eine andere Möglichkeit gibt, dies zu überprüfen, als sich die Dokumentation oder die Funktionsinternale anzusehen. Wann immer Sie daran denken, eine for-Schleife zu schreiben, um einfache elementweise Operationen durchzuführen, überlegen Sie, wie Sie dies mithilfe der Vektorisierung tun. Mit genügend Übung wird es für Sie zur zweiten Natur. Für weitere Details kann ich diesen Blog-Beitrag von Noam Ross empfehlen .

gersht
quelle
@ AnonMousy hilft gerne weiter. Wenn die Antwort Ihnen helfen würde, würden Sie sie als akzeptierte Antwort auswählen, indem Sie auf √ klicken. Auf diese Weise wissen andere mit einer ähnlichen Frage, was auch funktioniert hat.
Gersht
0

Grundsätzlich sollte dies auf der Hilfeseite ersichtlich sein help(function)oder ?functiondie Antwort geben.

saudisch
quelle
Das ist ein empfohlener Ausgangspunkt. Wenn Sie in dem von Ihnen geschriebenen Programm nach Möglichkeit vektorisierte Funktionen verwenden möchten, ist dies möglicherweise eine zusätzliche Belastung.
Anon Mousy
1
Dies beantwortet die Frage nicht wirklich. Es ist nur ein Vorschlag an RTM.
IRTFM