2014-06-26 8 views
5

Ich habe kürzlich mit dem Erstellen meiner eigenen Pfeifen gespielt, mit der fantastischen pipe_with() Funktion in magittr. Ich suche nach der Anzahl der Rohre in der aktuellen Kette (so kann sich mein Rohr abhängig von seiner Position in einer Kette anders verhalten). Ich dachte, ich die Antwort mit diesem Beispiel aus der magrittr Github Seite hatte:Wie können Sie feststellen, ob ein Rohroperator der letzte (oder erste) in einer Kette ist?

# Create your own pipe with side-effects. In this example 
# we create a pipe with a "logging" function that traces 
# the left-hand sides of a chain. First, the logger: 
lhs_trace <- local({ 
    count <- 0 
    function(x) { 
    count <<- count + 1 
    cl <- match.call() 
    cat(sprintf("%d: lhs = %s\n", count, deparse(cl[[2]]))) 
    } 
}) 

# Then attach it to a new pipe 
`%L>%` <- pipe_with(lhs_trace) 

# Try it out. 
1:10 %L>% sin %L>% cos %L>% abs 

1: lhs = 1:10 
2: lhs = 1:10 %L>% sin 
3: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 

Die Zahl auf der linken Seite ist die Pipe-Nummer. Allerdings, wenn ich die gleiche Kette erneut ausführen, die Zahlen nicht neu starten bei 1:

> 1:10 %L>% sin %L>% cos %L>% abs 
4: lhs = 1:10 
5: lhs = 1:10 %L>% sin 
6: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 

Dies ist vermutlich, weil die lokale Umgebung durch den ersten Einsatz von %L>% erstellt nicht, wenn die letzten %L>% in der Kette zerstört wird ausgeführt. Um also die Position einer Pipe in der aktuellen Kette (und nicht erst seit der ersten Pipe in einer Sitzung) zu bestimmen, muss es möglich sein, die Zählvariable auf 0 zurückzusetzen, wenn eine Kette endet (oder die unmittelbare Umgebung).

Hat jemand irgendwelche Ideen, wie man das macht?

Antwort

4

Im aktuellen dev Zweig, arbeiten wir mit einem neuen Ansatz aufgrund des zusammengesetzten Operators %<>%, wo das letzte Rohr wissen muss, dass es das letzte ist. Wie auch immer, die Implikation ist, dass eine Leitung relativ schnell Kenntnis davon durch einen lokalen Wert toplevel hat, der entweder WAHR oder FALSCH ist. Ich weiß nicht, ob das nützlich ist.

Insbesondere weil pipe_with wegen des sehr beschränkten Interesses, das darin empfangen wird, "gehalten" wird. Es ist daher kein Teil des aktuellen dev Zweigs.

+0

Gut zu wissen! Ich schätze, ich werde mich mehr mit dem 'dev'-Zweig vertraut machen und sehen, was ich damit machen kann. Vielen Dank! – ecologician

+0

Ja, wenn ich Zeit habe, wird Dev wahrscheinlich Meister und viele andere werden entfernt. – Stefan

+1

Siehe diesen Vorschlag für einen anderen Vorschlag https://gist.github.com/smbache/86fe703fa46e39df33ea – Stefan

2

Eigentlich dachte nur an einen Weg, es zu tun. Nur die Anzahl der Vorkommen des Teils zählen „% L>“ in den match.call:

> lhs_trace2 <- function(x) { 
+  cl <- match.call() 
+  counter <- gregexpr("%L>%", cl[[2]], fixed = TRUE)[[1]] 
+  if (counter[1] == -1) count <- 1 else count <- length(counter) + 1 
+  cat(sprintf("%d: lhs = %s\n", count, deparse(cl[[2]]))) 
+ } 
> 
> # Then attach it to a new pipe 
> `%L>%` <- pipe_with(lhs_trace2) 
> 
> # Try it out. 
> 1:10 %L>% sin %L>% cos %L>% abs 
1: lhs = 1:10 
2: lhs = 1:10 %L>% sin 
3: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 

es dann wieder laufen:

> 1:10 %L>% sin %L>% cos %L>% abs 
1: lhs = 1:10 
2: lhs = 1:10 %L>% sin 
3: lhs = 1:10 %L>% sin %L>% cos 
[1] 0.6663667 0.6143003 0.9900591 0.7270351 0.5744009 0.9612168 0.7918362 0.5492263 0.9162743 0.8556344 
Verwandte Themen